- 在线时间
- 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:3940376686 X2 _- u9 ^7 t! z5 k* \
2 r5 W& g$ ~4 |' U0 @* m Hamilton周游路线问题3 }1 M( m* _6 B+ `2 l) y( X
5 @8 C' P2 U o7 R5 B7 `- J8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。8 h- v4 {* h/ p
# _, a( G/ R. i, o对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
2 ?$ W/ s$ j( S) z# x' d4 H% Z$ W( \
! i) }( K# c1 g" Y
& I% _6 ?3 t' S E. W* v
3 K( T! E, Z Q) d- g- P" j//算法实现:
0 Y' y7 O+ C# b! f2 }& m& D6 Q& {( h* l9 R( H/ ^% S
#include <iostream>" `6 K6 v0 Z: O
#include <fstream>
7 k! r2 |& D/ ^3 I" t8 F#include <stdlib.h>
4 w3 E, l, r( j#include <afxtempl.h> ; @3 s N: n& n$ R+ }4 y; {& t! J$ w
using namespace std;
. E- X7 y% B. Jtemplate<class T>% L2 s( s( F& U
8 h7 N7 _( P0 m3 ~# K6 j
void Make2DArray(T** &x , int rows , int cols ) * J9 j( ?6 h; Q; ^
{
5 M. J, l2 a' Y- v8 L. a6 { //创建行指针
) u% U- a4 }5 E5 @ b x = new T*[rows] ; & ~( a* N( q& n; ]! H9 h( S g
//为每一行分配空间
& n2 v4 r8 Y* D; u& s. ~7 q for( int i= 0 ; i<rows; i++ ) $ f6 G& q5 E4 z2 j
{
) q' q7 o' @# n3 s) X x[i] = new int[cols] ;
5 n/ ?2 c9 ~6 i. i8 |8 o" \ } ; o/ E. L9 S2 n& N7 `: q
} $ P, {$ ]4 D* V. Z
template<class T>
* O( s) M$ j" A6 G! |) b. }" Y$ R7 ?8 y
void Delete2DArray(T** &x , int rows) " w8 ?3 v/ u/ [/ X) k( B
{
: O$ ] w' M. ^5 z- z //释放为每一行所分配的空间 2 ^8 N T0 ] q% v3 [4 }9 c& g' Y% l
for( int i = 0 ; i < rows ; i++ )
% m* J% X! ?8 Q {
2 |# \4 [; o) w X delete[] x[i] ;
. A: a5 P! v! B8 N( S9 ? }
& R) H8 l3 q8 ]% N // 释放行指针 . b. a6 n- @; q( V7 ?" t
delete[] x ; 5 Z( p( h2 J; ~: e. w3 Z
x = 0 ; 0 w4 K2 d% F, O6 v+ V9 x
}
; g% S! \4 f K" d. U4 i2 u3 q5 Q1 o# W
//其中,grid是表示整数对的结构。6 l' n5 J7 }5 S! r# ^3 N
typedef struct3 C$ q* x0 N' Y0 Y0 }( {
{
( w: O( b& D1 O int x;
" e5 M2 U5 E2 ~$ l9 J) ~: b int y;
2 u8 j/ p! {3 e" j( Z" L}grid;" q$ ~: G/ J7 L" U* E. Q/ ?
! _3 j" L' I+ b. [4 Z
//用一个类Knight实现算法。* Y& t% i( I5 d2 [2 d( B" F- }
" i, f( }5 @5 b5 D- t
8 R, P- B7 i4 k7 x- y: ~class Knight, i+ j- Z, d7 K- T; y
{
/ L. i! ?4 o( V9 I7 m9 l6 P) ipublic:( d \" b2 B# Y- v- c
Knight(int m,int n);4 P7 a/ `. B$ W5 w; j/ i
~Knight(){};
( H& E3 W' B0 A$ Y" U" n5 O+ \ void out();
4 p* O1 ]3 ^8 K9 n, b* ]8 G F% Pprivate:
Y/ _" G1 L n. ]$ U5 w; Q int m,n;4 Z: m, ?8 v8 e
grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;1 T6 f: g8 a1 U7 c
int pos(int x,int y,int col);$ S- B8 n _& _1 Z+ z- e- E, m8 C
void step(int m,int n,int **a,grid *b);
- G2 c3 R8 T5 i% W* p void build(int m,int n,int offx,int offy,int col,grid *b);/ Y# H& j; i1 V5 L/ Y
void base(int mm,int nn,int offx,int offy);: H1 y+ D/ v8 e* G% K$ b! _4 P0 @! ?
bool comp(int mm,int nn,int offx,int offy );3 c' F7 R, i, b0 { J% i
};7 [8 a; q5 |: f
; w+ v7 a' a. X/ u' b
! ~2 l% C( h* r) r% S+ k; k0 [; O/ i2 ^
* l9 O4 d5 M1 t" m# k: j1 _//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。
0 t! {' V& N! i/ F//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回路。' f4 m9 B; Z5 k1 [' J8 J
: ?: y. f% c$ p+ N, V2 C# d5 C% e+ q3 V! p9 ?7 Z s
//构造函数读入基础数据,初始化各数组。" J: A8 \4 _) f
6 b0 \, v3 ?" C- a6 N' X2 l
Knight::Knight(int mm,int nn)
+ r' s H0 ?& U1 D8 O! P# v5 Z$ m1 x& G{+ Z- n) P. S8 B8 ]* p* ]
int i,j,**a;
# U1 _9 D0 l/ N0 x5 _3 Y ifstream fin0;) b" j2 |4 P! R
m=mm;n=nn;
4 ]. Q. o2 p7 ^' A* i8 `, E# C b66=new grid[36];
( f6 _/ S2 V* c b68=new grid[48];& \* h: V3 f6 ]) k/ y
b86=new grid[48];5 W- `. I$ K3 s' o5 \& {) }
b88=new grid[64];1 Y* N. T6 K. E' a. Y* q7 P" }& I# ]
b810=new grid[80];
& d, [6 u: M% a4 ` b108=new grid[80];
# B. x* x: F; [2 t5 L3 R b1010=new grid[100];( p+ ]7 ?3 m! {- h0 Q3 q: B
b1012=new grid[120];
: e) S y2 {' H3 X% k' ]7 b: n b1210=new grid[120];
4 e" c" W& ?6 b6 y( R Make2DArray(link,m,n);9 ~9 }6 _2 O9 G( A: F* l% ^% i
Make2DArray(a,10,12);! Z* I* Z E- F& F6 ]$ x* F+ B
* Q9 E$ j9 b6 X! T4 _, h$ \
for(i=0;i<6;i++)
& ~: Z K v% M. J: H for(j=0;j<6;j++)
0 v, X$ t+ P5 V I fin0>>a[i][j];6 e8 R: g9 p9 P' v' V0 X+ ]; {
step(6,6,a,b66);6 v- ?+ \6 \; F% F" l7 O
for(i=0;i<6;i++)& m8 Y5 c3 o* L4 B% c
for(j=0;j<8;j++)
) j* @4 T4 j2 }0 a* } fin0>>a[i][j];, g: _1 |- l; `3 y! V1 d
step(6,8,a,b68);5 q5 |/ Z A# V/ r2 ]5 x Y& e; K
step(8,6,a,b86);6 n' Z$ v: L/ r. H& w
for(i=0;i<8;i++); n1 {+ q' f R3 ]' Y
for(j=0;j<8;j++) 3 k0 d/ `* g- ?1 [6 v; G ^
fin0>>a[i][j];
! K0 z: G+ K2 B# G7 c! \3 G step(8,8,a,b88);
! F0 ~: o4 i6 B for(i=0;i<8;i++). P( o- r8 ^% @8 x, x
for(j=0;j<10;j++)
) ?+ s( ?0 `; u7 p0 [) v! x fin0>>a[i][j];
( S, @" O; L: {2 z9 J# U step(8,10,a,b810); u6 f% \& G# h( ]* u; Y
step(10,8,a,b108);1 Y3 W7 |0 B5 X4 l
for(i=0;i<10;i++)+ A& [- ?4 H3 ]8 I4 D
for(j=0;j<10;j++)
* s' ?* x6 D1 i! y* E8 b fin0>>a[i][j];/ X; e8 s, ^3 }" ?& c8 X+ x
step(10,10,a,b1010);
" e5 K0 {8 Q8 R" o* h+ d4 q2 p; ~7 p for(i=0;i<10;i++)
$ f6 W2 E, i, r3 n( T, \ for(j=0;j<12;j++)
% a' z/ P$ t" H3 j' M fin0>>a[i][j];
. c) \: t9 ? {1 K/ G' I step(10,12,a,b1012);$ Z) Z- r5 C2 C. o% L1 o
step(12,10,a,b1210);
8 x! @) X& F# ~' W
4 \6 H# ]8 q6 B8 Z g}* r9 F7 L# U; N4 L% C& z
) T+ f) f$ s8 }5 |
5 P% x; z3 h$ B4 o
//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。
# y) D0 Y* m0 b& ~2 D0 D
* ?8 V' r: h4 v9 g& u8 d# ovoid Knight::step(int m,int n,int **a,grid *b)
. |" W. z0 S ]9 L5 P8 U- _{
! {. v/ l$ [+ |' s$ m) @% ~$ ?; j int i,j,k=m*n;# ~% A8 u- A2 `/ B2 I3 y, Y
if(m<n)3 X# B: B& ]4 y9 j
{
7 H6 z" @/ p$ _* B! A' y; t for(i=0;i<m;i++)
% Y9 |3 z( u) K: _2 c( J for(j=0;j<n;j++)
8 x; ^" c+ C; n+ S+ {( N# f+ T {6 l# C, x9 b) t' S; C" W: A7 s
int p=a[i][j]-1;5 L: n6 a6 t" `: l
b[p].x=i;b[p].y=j;5 H& A) m4 e4 q0 `" |
}
8 A7 D) T% [3 { }
; r0 a% V. B& Q" p else{2 A7 g# s! k3 {3 r& b' A9 @
for(i=0;i<m;i++)0 X; i+ ]# }0 U
for(j=0;j<n;j++){
- ?3 L) W& y0 O- P1 @3 v W5 j int p=a[j][i]-1;
) |2 J" }3 B+ K; l0 } b[p].x=i;b[p].y=j;
) {5 ^2 N' p9 Y }
" [" i7 n3 Y/ s. r7 @# Z } d0 D; `$ l9 V' d
}" w1 X. M5 ]3 h- B
) T* G t2 S% E1 m* x/ o! {
/ K; v8 [2 V2 i
//分治法的主体由如下算法comp给出。/ V: B& ]& [8 a, T7 j/ [
bool odd(int data)+ |( ?. b2 ~1 l e( T% Q) e3 Z3 {
{( X! x5 M7 C7 I" K. B% y- K" q# m
if (data%2 ==0)
) B' v. X. @6 U% r# q; K. W( c, C! g {8 P# ~# p$ F% K4 F
return false;
* N. a8 V$ U" M' M4 y7 r8 d }6 L5 {9 H& c: e* y9 U& l
return true;& K! W6 x9 e4 u! Q* d, k
}$ v/ I3 {9 c) j- x& W; H
7 \8 s' ~6 }& ~
4 x1 p3 F- s1 Z! J
bool Knight::comp(int mm,int nn,int offx,int offy)
1 S6 n8 x8 F' q6 K' e, w{' s5 R1 P! r( O0 A. b' v2 I. X- ]
int mm1,mm2,nn1,nn2;& S* A! O) i, c. A9 ~7 w. Z. x
int x[8],y[8],p[8]; ]1 W# ^& R( ^: A3 O
if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;+ z3 u0 }- |' c: ^% k, p
if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解8 j; \# M+ O% K+ W
mm1=mm/2;$ D9 G( d- N# t; @
if(mm%4<0)mm1--;, n: L5 K. c3 c- \/ U7 |, _- y
mm2=mm-mm1;( I4 X% p& P7 o$ T; a/ z
nn1=nn/2;8 U8 x8 C/ T" G1 ?
if(nn%4>0)nn1--;
, n% q9 w, d; k! c9 Q, p' D nn2=nn-nn1;) J3 \. [+ T+ ~% y( P9 w, _6 U
//分割步4 M! }0 g! d0 a( L
comp(mm1,nn1,offx,offy);
: u" G" c- K; T4 v% m comp(mm1,nn2,offx,offy+nn1);
; b/ d/ L( O7 f comp(mm2,nn1,offx+mm1,offy);
% _9 x# a. V2 }1 U/ d comp(mm2,nn2,offx+mm1,offy+nn1); K$ [. \3 v. D
//合并步. H$ s3 ?5 t& z
x[0]=offx+mm1-1;y[0]=offy+nn1-3;
6 |3 U& d, ?" E1 M" m7 L x[1]=x[0]-1;y[1]=y[0]+2;
0 B& v3 _. m6 u" `4 a" e4 K x[2]=x[1]-1;y[2]=y[1]+2;( F: `5 e6 y7 T6 ?& i
x[3]=x[2]+2;y[3]=y[2]-1;8 l" a N! P& p, F
x[4]=x[3]+1;y[4]=y[3]+2;5 P C8 Q+ q2 [ p- c! w3 U
x[5]=x[4]+1;y[5]=y[4]-2;& I4 f; h! ^! h* A: O3 V
x[6]=x[5]+1;y[6]=y[5]-2;9 ?+ g# e, S5 J4 u) e4 v8 l
x[7]=x[6]-2;y[7]=y[6]+1;1 S) r3 W8 r9 e/ d( d8 @
: K5 A( n ^. W" N" a E9 c% m
for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);
* a( A- a! o! d# B3 j for(i=1;i<8;i+=2){
4 `3 c0 n2 o& U% T int j1=(i+1)%8,j2=(i+2)%8;- p0 ^# b& p( B$ e. Q) m# R
if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];
! P1 o6 U. ^' j( I% ]- N1 Z' Q else link[x[i]][y[i]].y=p[j1];+ z- \( u- P# W! k1 o7 |4 J
if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];& ~5 w0 a* r) R& r% B6 \8 m
else link[x[j1]][y[j1]].y=p[i];! T. p) D }) a# H6 Q
}% | I6 G: m v% I& c8 d! ]* F E
return 0;9 G' x- G3 a+ e4 ^
}; a8 M9 z8 F4 \+ N! L1 N8 k
O0 [# J& ]/ Z" e- _
: `: |) F& _! ~8 u. h//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。
7 }$ i' e' Y3 z$ L1 \: [( W; @4 Y1 z
void Knight::base(int mm,int nn,int offx,int offy)0 m# U2 s5 A) R) {
{
0 Y0 K Y0 o3 u6 [* o# s7 y if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);( }4 i, B+ e4 X b
if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);) o- b d* y% B! S. e V
if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);
) s( O0 T# [% |2 v$ j if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);
" A* p/ C7 q; J3 T5 a7 B+ C if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);' v$ `4 i1 |, y; i0 A2 i
if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);7 t2 @. P# \" X, x+ V9 R! C+ ?
if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);
+ K) Y3 ^* h/ \0 P if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);
# X# S; A! B* t, D, x- Q3 a4 G if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);
, ]* K* o; w* c4 O- z! w1 U}
+ p# b7 C, _9 S- Z
6 y# \' |- M3 w8 Y" R4 m$ W7 |3 Z1 ~: W' }1 N
//其实质性的构造由算法build来完成。/ g8 x8 Z8 n* U+ ^6 B6 |
5 P& T+ d, h4 Y3 x
void Knight::build(int m,int n,int offx,int offy,int col,grid *b)
" t0 y, z* z& c; G$ j- t{( p5 G$ _6 Y4 l9 l9 {8 Y
int i,p,q,k=m*n;6 S4 }' Q& M, i* u2 W9 W& j- m
for(i=0;i<k;i++){' W- x/ `' T) T6 A* e
int x1=offx+b[i].x,
/ j5 Y4 b3 k a y1=offy+b[i].y,5 D" S( @5 P0 w6 l
x2=offx+b[(i+1)%k].x,
; o& ~5 W: T& n% b y2=offy+b[(i+1)%k].y;. b3 f4 m) {' D( X+ t
p=pos(x1,y1,col);q=pos(x2,y2,col);
: d/ ?# X- w1 K5 |. G( Q) O- q link[x1][y1].x=q;link[x2][y2].y=p;; \ z( \8 U' ~% [: s
} 6 t4 i; w, x$ _
}& H4 L) F" Y& ?4 x* K" \ q
6 h+ \: M5 a% V, P3 k( ^ b j# |3 [; f' _/ h7 H
//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.
8 K" z" U1 E& I8 {) c
: ?/ c) Q7 o% x9 k. I' \4 \* wint Knight::pos(int x,int y,int col)
0 z% Y7 D' ]: z% `{$ n. I5 D! C# i$ d" ?7 L! D# D
return col*x|y;5 _4 i6 a2 f I2 |3 |! N' h# r
}9 ^( s7 Z Q0 Q: _
. L* }) j7 e) p, j! D5 R. p% T# M" t3 C2 C2 t0 b. W- u7 [
//最后,由out按照要求输出计算出的结构化Hamilton回路。
9 I1 |, A! ~' c4 z( k0 A0 K' y2 Z, M
void Knight: ut()
! z s( H5 Y0 L0 g9 T! @( I: C" \{
. z* z: o* ?" ~( C: `3 ` int i,j,k,x,y,p,**a;; j5 X$ B' v9 d2 H5 ]
Make2DArray(a,m,n);5 V4 N& \" y& ^2 _3 _ R
if(comp(m,n,0,0)) return;4 k, a9 a, ]/ e* @( W; H
for(i=0;i<m;i++)" ^/ C* R8 c1 ?$ G; }( s* q
for(j=0;j<n;j++) a[i][j]=0;
! V7 O/ j: K( o- c( U i=0;j=0;k=2;a[0][0]=1;9 B+ g. a# B: ^- q$ U
cout<<"(0,0)"<<"";
4 T- y& S, N. H5 _ for(p=1;p<m*n;p++){+ F) E- g3 c. s3 v- j' @" u
x=link[i][j].x;y=link[i][j].y;; i) i [! x/ q; t6 ~3 ~9 i
i=x/n;j=k%n;3 Q5 p$ |6 S B6 N# {
if(a[i][j]>0){i=y/n;j=y%n;}/ U% a( @6 v2 f' g3 g
a[i][j]=k++;
! \ x* E, P }+ _, u$ [ cout<<"("<<i<<","<<j<<")";
; z7 M# H1 ~7 A. L5 W if((k-1)%n==0) cout<<endl;9 x5 m3 k3 z' ]5 J' K8 Q* ?6 A
}1 H+ B) i9 r% ~8 K2 X T8 i
cout<<endl;
! Y; k7 \2 U# c0 I% F" ^" x for(i=0;i<m;i++){7 } r3 i1 ?( f* F$ \
for(j=0;j<n;j++) cout<<a[i][j]<<"";5 ]) |/ W5 M" _3 z, e
cout<<endl;
* `# f) i: L+ a5 `- s# L5 w }
7 c- h, ~- d* o$ ]2 X} |
|