- 在线时间
- 8 小时
- 最后登录
- 2013-6-25
- 注册时间
- 2010-4-17
- 听众数
- 3
- 收听数
- 0
- 能力
- 0 分
- 体力
- 128 点
- 威望
- 0 点
- 阅读权限
- 20
- 积分
- 88
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 102
- 主题
- 3
- 精华
- 0
- 分享
- 0
- 好友
- 1
升级   87.37% TA的每日心情 | 奋斗 2013-6-25 15:34 |
|---|
签到天数: 8 天 [LV.3]偶尔看看II
- 自我介绍
- 200 字节以内
不支持自定义 Discuz! 代码
群组: 2013认证赛A题讨论群组 |
调试的时候就是有两个问题,弄了两天了,我也不好说,哪位高手帮忙指点下:非常感激,急急急!!!!! qq:394037668% A7 M! P! i. O3 T1 K$ ~- r
1 D% Z3 M x9 j0 G6 G Hamilton周游路线问题+ w) t5 N: k; e0 _5 K' ?: u. K% |' k
: B' C8 X H" E! h/ v! c$ O. L8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。3 P q/ z2 N% C2 e3 _+ B; _
* e# Z9 G7 O( D z$ g4 P对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
4 [- ^! k% J& X# \' \2 j' b& ]* l( Q- n6 b0 Y1 e B
/ `0 S9 q7 S" E& }5 x3 K% Z6 O8 n' }
//算法实现:( K6 g4 a8 I; q/ S: ?+ P- P
8 I4 E0 h0 C+ h#include <iostream>0 A- [( Z6 o$ R' J3 k5 p2 h
#include <fstream>5 T, R1 g& f5 T; z, e, y
#include <stdlib.h>6 S; p! Y3 S, y
#include <afxtempl.h>
: T3 x! @0 W6 {% ousing namespace std;
( P7 c" a6 O5 }, S: ]( n1 G8 ktemplate<class T>
+ G, ^$ Y" K9 @& S0 K+ b) ]
" T" h. |' |& A/ H, Rvoid Make2DArray(T** &x , int rows , int cols ) / [3 ]% x3 j9 t' O4 Z! f
{
9 o1 m, K/ ~) s; _5 @& H //创建行指针
$ t" O3 v! N. Y4 c x = new T*[rows] ;
- w5 r, x0 X( E0 p2 E# X //为每一行分配空间
$ C0 ^7 W+ q6 t6 v/ l/ g5 X for( int i= 0 ; i<rows; i++ ) 3 }0 r: O( i% Z+ `9 `6 E% P
{ # _4 K6 ^$ E7 C$ f" P- `! w
x[i] = new int[cols] ; ' Z+ H& F4 z+ Y/ s
} 9 K4 S# L4 g: B9 [
}
3 k$ k: m9 t6 M) y. H7 M, ~template<class T>8 t* I$ ~% i3 U" O: X A
6 V1 x- ~% ^) {# X* Q. }
void Delete2DArray(T** &x , int rows)
" L; N9 Y2 X% ?' g& x{ . U: c" Y. {6 b W2 j4 z* Z
//释放为每一行所分配的空间
" r8 E D# \ R for( int i = 0 ; i < rows ; i++ )
e# F* r+ N `& u4 _4 g/ Z# p' x { 1 ^! H" ~ q, A" }
delete[] x[i] ;
& [8 s! i! j- q( N } 6 x0 J1 ?% n* N
// 释放行指针 ' y1 H% l# \: N, M4 r
delete[] x ; 8 Y0 @5 A" \7 }' y* T
x = 0 ;
+ ^; A/ F/ p4 v& R}
4 P0 o# H" J Q2 P4 |: Y" ~6 g" ~) e) K" w F) A2 ^" \
//其中,grid是表示整数对的结构。: C: U' `$ S2 {* J! o3 J! x% {3 ]. F
typedef struct
+ @1 B2 ]( P% q: j3 S{
6 s* l$ q( s9 e; s' I/ O int x;! ~& J; Q% ]: A
int y;9 X2 A- i; W+ U3 K t
}grid;
9 n4 [4 ?" ~4 I3 x4 b( N0 m
8 ^ p! ~* f$ w3 F, t1 `//用一个类Knight实现算法。. E7 Y$ h0 ^0 o7 A4 e U
: u( ]7 U" z' R( H4 {! K( ~' @) |1 V
class Knight
$ B6 Y7 w. u3 v" ~{3 T. J5 f$ S& f8 i; n. Z+ Z
public:8 x) l, u4 [ B* b
Knight(int m,int n);
' C+ @& `% r* ^; H6 y |4 _4 J ~Knight(){};' a# l0 K3 {+ p' c
void out();
4 W+ k4 W4 `$ @$ m7 ]( w/ }private:7 U$ H# u1 C# Q7 [
int m,n;# Z1 C; V4 ]! z% s* H
grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;8 Q/ M+ i( d6 p) Q$ [
int pos(int x,int y,int col);/ Z$ T* h% B$ Q) \3 D4 A
void step(int m,int n,int **a,grid *b);! X2 f8 V, o/ B' o! N
void build(int m,int n,int offx,int offy,int col,grid *b);) Y+ |3 q, x8 ?: e5 B+ `. f
void base(int mm,int nn,int offx,int offy);
# v, D/ u; z2 {, X m3 h i1 F- j bool comp(int mm,int nn,int offx,int offy );9 d7 T7 h) J3 l. ^' T2 J5 m
};+ k9 X2 G# J9 E+ T
% }! v6 S6 Z7 l* b/ M" }$ o) k# g
4 n. W' O: b! J, t' e8 @- V4 j" X1 K/ o& Y
/ W8 e) W9 d) C& D, _( n! t! \//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。
9 H3 {+ i7 Q) s. ^//b66,b68,b86,b88,b810,b108,b1010,b1012,b1210分别表示6*6,6*8,8*6,8*8,8*10,10*8,10*10,10*12,12*10棋盘上的结构化Hamilton回路。
; K) E/ W% L* E2 q4 h3 K9 x. U3 Y( ~# J8 |% \) B
) ^2 Z/ R2 p- M/ C& e//构造函数读入基础数据,初始化各数组。9 X3 \1 v$ l9 N' u
7 m3 y$ n% s6 K7 E1 aKnight::Knight(int mm,int nn)
1 J" s* b8 f0 K9 f Z R2 @{5 N, A& Y) k; T- ^$ f
int i,j,**a;# f0 \3 V% h2 r* @ ]
ifstream fin0;
# F) M. @+ w- p' _ m=mm;n=nn;
5 U, q8 D- c V' Z) s$ J b66=new grid[36];
1 Q: s3 P7 ^) k& c b68=new grid[48];
5 L$ a+ r* t% m, L" t b86=new grid[48];6 e: \' V! Q# _! v% p- `
b88=new grid[64];: V, z$ w; X- t/ p) x" h# |2 y
b810=new grid[80];; _6 g+ q* F; h7 h/ C1 n
b108=new grid[80];
& \4 C0 q9 J( Y& l6 z3 c& K/ k b1010=new grid[100];
6 K+ K3 A8 w8 V) K' O7 n! G b1012=new grid[120];
9 P9 J# G( m* v7 p: E b1210=new grid[120];
W2 C# w- N2 F A Make2DArray(link,m,n);5 Q' K1 d i6 ~) k) M( ~
Make2DArray(a,10,12);
6 p B$ j- t% O' D1 B$ H3 `$ D, l
a" ]. x/ X% t& p& x for(i=0;i<6;i++)
; F: Y/ a/ V5 a/ R for(j=0;j<6;j++)
: u$ J1 ^" s5 Y; p2 ]7 n5 [ fin0>>a[i][j];2 ~3 Z! r3 h6 E H4 }4 y
step(6,6,a,b66);
) i% P( |1 @, K' p x for(i=0;i<6;i++)9 V, c9 T. r1 h
for(j=0;j<8;j++)
( |. r6 f c6 C7 ?, D8 [ fin0>>a[i][j];
# }- C" w3 W& _* r" V5 E step(6,8,a,b68);' c* J6 {# x0 `
step(8,6,a,b86);. {- c4 _, F. [. N r1 G
for(i=0;i<8;i++)
! [8 l2 j, R# e% v( }7 l for(j=0;j<8;j++)
1 Y+ Y; Z7 J; S( K6 @' c, U! y# f fin0>>a[i][j];3 [5 I. L S- {" [ i. G
step(8,8,a,b88);
4 y, w$ K9 j" H$ c4 {( g: b# E for(i=0;i<8;i++) Z( P/ }2 \! l& t u
for(j=0;j<10;j++) 4 E8 P4 t6 [; Y7 x( n0 F
fin0>>a[i][j];
% H1 ~9 S# S* l' Z1 z step(8,10,a,b810);
# N. Y; C" I4 ?8 M+ | step(10,8,a,b108); X: T n- Q# l7 ?8 n6 I
for(i=0;i<10;i++)
1 z) }4 k* i# b6 z- e* b for(j=0;j<10;j++) " M; J& h( m$ ^6 _1 {
fin0>>a[i][j];
& h! ~/ A8 B: M# h step(10,10,a,b1010);6 q2 R. d; S% [
for(i=0;i<10;i++)
) T) P2 O0 N; ] for(j=0;j<12;j++) 7 C7 y$ D+ j4 Z/ D- K$ Q9 ?
fin0>>a[i][j];
4 t- ?/ l3 Y3 F, P" U, D step(10,12,a,b1012);
8 t$ I) @( e4 v, x2 y J8 d% n step(12,10,a,b1210);( p# e. x/ _9 e( ^/ J
" y) C' o' Z% E3 r1 I" T+ [* \}
( T0 p3 }. P/ e2 z" x
0 `2 Q2 }* F% A! Y% F
7 C3 h- q" d8 x9 D//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。. C- e) f) u8 M, F
- ~. M; @3 h" I& {2 m3 y: D: qvoid Knight::step(int m,int n,int **a,grid *b)6 S" u) s. v1 R, w1 Q$ M# o
{# K3 X7 M3 r% F; g! x& ~
int i,j,k=m*n;1 H2 r7 q" j( B/ O2 i" p
if(m<n)
+ \& F! ]& c0 w8 {" [5 k X H! x {2 j$ `6 H3 O! G0 K, I& x9 }
for(i=0;i<m;i++)
6 K; r, E' i2 U7 O- _ for(j=0;j<n;j++)6 j7 o: V$ {8 W
{, g+ V7 }3 Q: M! F% h# O+ c
int p=a[i][j]-1;' _0 d/ [$ [- S3 f$ Q! g9 f8 I
b[p].x=i;b[p].y=j;
4 Q5 b) i0 K* G1 {7 E }
: z8 o+ l) U- q6 S% o }
0 k3 A# Z# R: C8 f" p0 E) ^. z else{
2 v7 S) q0 r* }: t" P: E for(i=0;i<m;i++)7 e. F: a/ y* O$ v$ _! q
for(j=0;j<n;j++){
' S- `) A. f1 ^& n3 d int p=a[j][i]-1;
8 G& @! M$ v. R0 }/ I8 \% C& E b[p].x=i;b[p].y=j;
& a. N# |5 A3 Z7 P" d# _+ w; G }
. P9 [, ^3 R7 o7 x# ~( O( U* W2 u6 q }
: m9 Y1 }4 q! C* W$ P! a}
/ A1 |! v. ]& j2 p
& h/ b* o+ o, L" y
( r' [4 }" S& l7 t//分治法的主体由如下算法comp给出。
5 w' X8 v) g. L v2 p4 K/ A1 U- A/ |bool odd(int data)
; @7 r& F V0 T- s% o{2 d8 z8 ^# j5 O) j2 d/ ]
if (data%2 ==0)* A. o2 D. g, r- Z7 f, Y5 T0 L; A
{
/ F) A5 N3 i: J4 D3 \ return false;- V4 o; z1 t- U3 X2 j
}
- C9 v: t. r+ S5 X return true;
2 ]5 T8 P1 p& V8 b}+ ]. R( a2 D3 Z# ?. \. [
$ B X3 H7 t/ a- w7 T* t
! i" o$ m5 ~. q% d: H- Ibool Knight::comp(int mm,int nn,int offx,int offy)
# x% w* ^: i! c0 V( @$ W4 J. Y; N, g{
3 W5 ^" p- n$ n: k, @2 J int mm1,mm2,nn1,nn2;1 E8 J. r. x- R1 y
int x[8],y[8],p[8];
' Q2 y& a- [0 H if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;
: n% i/ a/ c+ V5 K' |8 f* w if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解 q; u! H1 Z) R
mm1=mm/2;
& V+ z! `6 p7 p: X, N if(mm%4<0)mm1--;- f- P4 r! e- h; x7 X2 \
mm2=mm-mm1;
8 \: t7 Y8 K+ K! R* u nn1=nn/2;
5 g+ r5 ^: R0 R5 _( S+ K if(nn%4>0)nn1--;* z5 K& u! `0 K2 r( V8 g) L
nn2=nn-nn1;
5 F/ @9 E4 e; p% P- l& | //分割步
. q& M: c* A0 p9 `' \- h3 F comp(mm1,nn1,offx,offy);% N* ?$ Z) e$ |# K: r
comp(mm1,nn2,offx,offy+nn1);
. [/ X# o- r9 Y% u( P3 W comp(mm2,nn1,offx+mm1,offy);
, w) m( D' }- U7 f# i! _ comp(mm2,nn2,offx+mm1,offy+nn1);+ V8 `2 M9 E9 Y$ \ @$ M) q, T" k
//合并步* T' h( K" b( @( F$ V' j+ v" M
x[0]=offx+mm1-1;y[0]=offy+nn1-3;7 d* u# L: c3 T: m
x[1]=x[0]-1;y[1]=y[0]+2;
/ Q/ t9 y2 {! c& B4 V' r! } x[2]=x[1]-1;y[2]=y[1]+2;
y; \0 f/ t' F* P3 Q x[3]=x[2]+2;y[3]=y[2]-1;& R, N7 d/ L% q1 z5 E
x[4]=x[3]+1;y[4]=y[3]+2;
~8 _- \+ G- I+ J0 }! w; R2 h, I x[5]=x[4]+1;y[5]=y[4]-2;
$ F1 R8 ?: R- M x[6]=x[5]+1;y[6]=y[5]-2;, C. Z( D+ X/ X l
x[7]=x[6]-2;y[7]=y[6]+1;
% L" W% U9 I: Q- x, L ^
, q: L4 s" D& J+ ^! ]+ U' L for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n); z5 k8 P+ |' [( H; _: C; h& X) K
for(i=1;i<8;i+=2){
, B) r: |: k4 G7 R int j1=(i+1)%8,j2=(i+2)%8;
2 w1 s: X; H Y# R I9 d: j if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];
: f( g6 a. p; r7 d- B) U" i! S else link[x[i]][y[i]].y=p[j1];
; ~! ^; c; N( } if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];! ~, d. ?# X& J" j) M) ?* A
else link[x[j1]][y[j1]].y=p[i];$ J0 q% M1 ?# j+ V( `, G- {
}
, N( \% L. m' p' n' }: A6 Y" | return 0;+ j& h0 I6 h5 G2 a6 Q8 T. X0 u. a
}
3 E4 A+ Y4 X" c% a* k1 Q- M& f
) N5 q L! Q7 D, b0 f" ~; l7 [. f( w% m$ C. h9 Y
//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。
! U& K& m5 e2 I' L2 j. t
* @$ F0 }4 r0 @6 h2 j! ^' ^void Knight::base(int mm,int nn,int offx,int offy), e, f0 Q0 T5 F; f
{8 T% o2 f5 Y$ k& O. O
if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);7 ?4 Z( G8 T9 o7 m( R& g
if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);6 _5 @2 s4 @ H! e
if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);
' F. A4 m3 k; {( e5 c if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);+ C' B; |- w0 Q' z1 ^- x; E/ }
if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);3 }7 j9 I& J! Q8 e0 H! H5 j
if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);
% {! V" A: R; |, a9 o: t/ w7 z ` if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);
0 G P' D; U$ K* h7 R+ y4 ~ if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);
9 l3 g) Q$ Z$ t3 ]: F, Y if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);; i8 t, s S2 O6 T8 I9 D& J
}
. F3 t) a7 b8 r' V: F3 `
0 r5 d. N8 c4 O% z0 r7 O5 O, b
, D7 H1 W( m# B ?& j$ y* ?% m( ^//其实质性的构造由算法build来完成。
1 D& t, |5 k9 b/ b. }! U* q6 l
void Knight::build(int m,int n,int offx,int offy,int col,grid *b)
- l" D0 w+ n& p& T# r/ u8 m8 X3 z{( B( e3 I2 E+ j T, T0 A0 _
int i,p,q,k=m*n;- }1 e7 C8 [; K0 A1 r
for(i=0;i<k;i++){
$ U3 W" B( j% W* o* I& O int x1=offx+b[i].x,
& ^, o, z% y" a: D# D, c y1=offy+b[i].y,; O: X. k( h4 x: w: i1 D7 w
x2=offx+b[(i+1)%k].x,/ n' b0 w: D$ L) `+ a1 ]. N4 t
y2=offy+b[(i+1)%k].y;
. O& A, X8 k/ r9 W9 Q p=pos(x1,y1,col);q=pos(x2,y2,col);) `5 w n/ h4 Y: x6 h+ W
link[x1][y1].x=q;link[x2][y2].y=p;
! {. B+ ^) f( U } . z1 q) Y5 P) v' V) Z7 i' y: c* K
}' ~9 k) l+ s: ?4 e/ ?" g3 T( m+ N
# r. u% T" h# t) s* B, _: E, ]& i8 L r& K W" G
//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.
1 M a- _6 l7 _- l
+ E `: l. p2 t0 @" E* Yint Knight::pos(int x,int y,int col)- |4 ^) A$ ]) T9 X4 S' [! @
{( H) t0 N! |1 i* ^- J3 U4 ^
return col*x|y;' @' F1 Q/ b/ g$ M# n+ u
}# d9 |6 s3 O: v( v* W8 U6 d7 U
/ v# |$ a% E% M
! J# ], h2 F$ X//最后,由out按照要求输出计算出的结构化Hamilton回路。) ~$ L `) o5 {
7 h7 D+ b e( e8 K- H5 {void Knight: ut()
" l Y1 G2 x3 ^5 M+ D. C{
) M, V. H5 s, z/ C# d- L2 z1 Y int i,j,k,x,y,p,**a;
9 E2 M( s% {3 q S0 U u Make2DArray(a,m,n);4 N( g$ B: k) T& p- f2 F% `
if(comp(m,n,0,0)) return;9 F( J% E2 O. z: z$ q ]
for(i=0;i<m;i++)
% T" b* Y& B( T. ^( K for(j=0;j<n;j++) a[i][j]=0;
9 x1 g, P. `4 l( O i=0;j=0;k=2;a[0][0]=1;$ V% \# R! Z, P2 b
cout<<"(0,0)"<<"";
$ V, j! B/ ? _1 V* F for(p=1;p<m*n;p++){
; x$ d% O0 d# B& v) {& y x=link[i][j].x;y=link[i][j].y;
" p6 e+ v8 }) A/ M& \5 c8 L i=x/n;j=k%n; b! v* t* U5 h) n! Z; M9 a
if(a[i][j]>0){i=y/n;j=y%n;}, x, r4 n8 E/ M! \0 z
a[i][j]=k++;% R4 [4 z/ k& v9 h% S9 c7 Q
cout<<"("<<i<<","<<j<<")";; H/ B( O/ m* A, k
if((k-1)%n==0) cout<<endl;
2 U% h+ l; o k& Z8 \ }5 v- k2 @ D9 Q
cout<<endl;
4 I. m/ }5 K0 k( {4 {+ J for(i=0;i<m;i++){. R% Q! ~! H3 K) y2 q+ ~9 a
for(j=0;j<n;j++) cout<<a[i][j]<<"";9 ?: ]: |" ~) v( O. H0 l# R0 I
cout<<endl;
/ R% U0 k5 q1 z9 t. H3 b i }1 _1 ~: k7 z5 W7 y) B/ ^
} |
|