- 在线时间
- 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; B: R" n; D/ O( ?
0 j8 A8 P7 T2 W. B0 { Hamilton周游路线问题
+ V T2 G# o J: ?; |& F: h$ Q% V, i$ ]: |% w
8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。; Z1 \: T4 I; z# ]! X
' \9 ]+ a9 u. }" p7 ~" o" {对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
$ G2 [& C+ z" x4 {% i+ a# n
" p6 E+ e& V1 G& v( M* T# N
+ n! ?6 n3 `- g* Z, F- Q/ s+ S
3 q! C- y3 {3 M- p {8 l5 z9 @//算法实现:6 Z; Z1 k" Z8 B% o6 u" _% B
' d( r0 L+ B. o& L0 ]0 _
#include <iostream>
! _ W# Q' X4 F#include <fstream>! M- J3 D8 I% W; ~
#include <stdlib.h>5 T7 O/ }9 c5 Y& h; y/ y: y( j
#include <afxtempl.h>
" s) S" Y6 b0 R# u+ G/ yusing namespace std;
' v0 e9 l8 x2 y5 h o1 h' ctemplate<class T>
$ U" _9 u' Y% a8 }- x U( a9 d( _2 ^ M8 D" p5 O3 |
void Make2DArray(T** &x , int rows , int cols )
2 S: Q/ |% e4 F+ ?. D{
, e8 p6 X/ I- X! ?. a //创建行指针
; o. m( n) T/ r. }) E) q x = new T*[rows] ;
! J* z4 x" H& T/ E1 G //为每一行分配空间 / e* b0 n2 w7 l% c0 m; t( C# }3 b5 f
for( int i= 0 ; i<rows; i++ )
0 e7 m9 R7 _* k1 A, r' | {
$ F, u( s; [2 _) n: j& A* d x[i] = new int[cols] ;
' @1 X! D7 [2 u& \ C& J l4 ? }
- b3 p: `8 U+ f* I3 g6 x) x8 ~& o}
* n4 K5 J R. Y- Z/ @ mtemplate<class T>2 \) g0 M4 B/ u
1 N! l) \6 k% v3 r
void Delete2DArray(T** &x , int rows)
: P) J, v/ H: R{
: C* F- Z0 w4 Z- e% E //释放为每一行所分配的空间
2 `6 B- V, o1 g7 E% p; h for( int i = 0 ; i < rows ; i++ ) ) O I% P! C) K# [# v6 T
{ 8 ?$ R' T j4 `( t
delete[] x[i] ; 6 O0 P7 k1 ?# v7 j8 R2 K
}
: {3 }; Z/ W& Z) A: Q+ q3 o // 释放行指针
: n9 H: a: N! } delete[] x ;
& v9 |8 H: O& ], R x = 0 ;
8 s( B9 N5 i( M/ H, Q}
7 y9 R) @* I! n( i8 h4 i/ F; x
$ l$ ^ E- {0 y2 P//其中,grid是表示整数对的结构。6 B* f3 `) H$ P8 R
typedef struct
5 K* I W [. f* @2 g{
6 F* P3 @ W7 C) w int x;
6 _+ i$ y" _7 O# {9 { int y;0 R0 n4 v4 S5 p
}grid;) [; ]; Z0 E2 L: [; T
/ m4 F* ?( O9 P' [: i/ ^6 ~* a
//用一个类Knight实现算法。
( e, J/ c7 I5 e- N' i
1 b9 O1 _# o& F# m! N5 a
/ ~4 ?" E4 q. i; }* F) V3 A- jclass Knight" |2 p( F9 Q/ L5 f
{
4 W7 ^6 _; v( H9 z8 _public:& C) q. f: O2 u C0 C! ^$ i
Knight(int m,int n);
) s, ?/ b, H' ?: t* e* t ~Knight(){}; E2 ^0 ?6 P4 ?2 b
void out();3 C( P1 G( n2 ]3 r" x
private:
J$ f# N; w$ e+ V/ J7 L& O int m,n;2 z8 M! X1 g! ?
grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;. b' ]; g7 [1 w* U/ s
int pos(int x,int y,int col);
9 r" ?* _. ]2 Y T' _# m' l5 w void step(int m,int n,int **a,grid *b);
# V T7 w+ f6 ?4 m. k% g/ w% L9 P void build(int m,int n,int offx,int offy,int col,grid *b);
2 b" b# y0 S( H void base(int mm,int nn,int offx,int offy);1 J% C5 H' p/ Q7 C* l$ n/ x
bool comp(int mm,int nn,int offx,int offy );8 N8 l4 K: h! o9 A' K" f
};
* l+ V# Z! }# {9 {& ~
0 N3 I5 P1 I& J0 O" z; l3 v
: ~* ?2 i) A1 [ o- `. X+ \7 M
$ d* a' P: O+ L$ K3 O
7 o: E$ p" R+ @. X) K& k( l//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。% J) [4 {( t# T q
//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回路。& a0 q1 r) H- S/ t) N
9 Q. N% f" |5 J+ q% i5 Z( @9 p+ R% b) o/ {
//构造函数读入基础数据,初始化各数组。3 o p3 t/ Q8 x9 P5 i o
s3 @" ^, c1 z0 H1 G# m, pKnight::Knight(int mm,int nn)$ K7 s- u3 R& s/ W& U
{
8 f# r6 d+ z$ O0 v$ X% f/ | int i,j,**a;
9 Q$ R2 }+ v" N# ~$ N; G. G ifstream fin0;
+ r8 ~2 p( }7 z1 `$ Z4 e m=mm;n=nn;6 O2 c3 K( L# G5 q v/ i: J
b66=new grid[36];
0 M% {) D$ V- Y9 r b68=new grid[48];
; {0 N, p% `) U F' r+ e3 z7 I; v+ f b86=new grid[48];
7 C* o2 D3 a7 k b88=new grid[64];
* @" S0 G* L5 Q) E, t b810=new grid[80];
( C' ]3 o. u% i, `' S$ \& m2 @ b108=new grid[80];
! c+ M* @* B7 N0 N4 ^! O b1010=new grid[100];
& H# M) n; F6 x0 q b1012=new grid[120];
. p6 M" f+ Q- c% ] b1210=new grid[120];. Q% N2 T6 d; D8 B- g4 J; `
Make2DArray(link,m,n);
; ~5 \! j& g2 t Make2DArray(a,10,12);7 G5 Z% x. m' j6 G
1 X l: N U; h, a
for(i=0;i<6;i++)
- m" I( e8 T0 v- S, T for(j=0;j<6;j++)
8 l; {' z: S; H. T) e/ Y% k/ B fin0>>a[i][j];
7 E# v' D5 I8 t# j1 Z step(6,6,a,b66);
# v' X8 R& Q- _2 _/ ?) k3 b6 ?5 R for(i=0;i<6;i++). m5 ]/ |% d) W! s$ Y+ i% r* B: j
for(j=0;j<8;j++) 2 ~" ?( [# d2 s' e' X/ C! W
fin0>>a[i][j];, @: |( W( p, K, |% W
step(6,8,a,b68);
: U7 A9 L, L4 u+ l1 f step(8,6,a,b86);
6 A4 G/ h# J5 t) ~ for(i=0;i<8;i++)0 m9 R/ T! {2 c& T5 a
for(j=0;j<8;j++)
9 D; o7 s1 }. }# p% l& h5 R+ z fin0>>a[i][j];
+ [8 d) c4 C7 x. G7 ^6 m7 R4 C step(8,8,a,b88);
! a( _$ M/ A( p8 v7 @ for(i=0;i<8;i++)1 I+ L: o9 Q$ u) u7 p! w
for(j=0;j<10;j++)
2 g0 @& ?. u: y4 j, j( q8 Y fin0>>a[i][j];6 c+ Q3 }; a+ E. w$ w7 B- x
step(8,10,a,b810);& E/ A; n+ U* X& t ?+ F3 {
step(10,8,a,b108);
# f ]6 g- a/ J3 \# j# l for(i=0;i<10;i++)4 `* q4 p% \) a8 `
for(j=0;j<10;j++) ! t3 W) r7 w0 O5 d& `
fin0>>a[i][j];+ b" {2 C7 X# _: l* j, Y: J
step(10,10,a,b1010);
# a8 O! B% i( [: z for(i=0;i<10;i++)
1 G/ B3 G( g: i+ |) o' ^& u for(j=0;j<12;j++)
7 ~2 y" T) n) a/ H M8 D fin0>>a[i][j];
2 N# g# V7 ^ u step(10,12,a,b1012);3 E& k5 d2 H. e- T6 C# B# _; S
step(12,10,a,b1210);7 r; _9 X ]6 g) Q6 k
; ~2 B# J2 A: y( w/ R+ l}
1 k8 [! i/ q! p& I! R2 _9 f! z- I0 a# E# w8 T: n+ `7 U8 O; c
* s0 k8 m! f! P2 O5 _+ \
//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。, p6 Q) Z6 G4 \! F l% P/ u* }
" x6 s0 w/ H* C+ w
void Knight::step(int m,int n,int **a,grid *b)
8 X( g6 p4 F& s9 O; u$ u{
, o$ ^( V' L. J: b/ K+ R int i,j,k=m*n;
6 x& c! f8 H& R% b4 |! a w+ H if(m<n)9 t% N" Z6 T! o1 V; u2 a& _
{6 F% Y p+ X! L( X* }/ I! `) G6 m
for(i=0;i<m;i++)
+ ?) V' S U, \% q O5 u5 ^9 J for(j=0;j<n;j++)
( D7 y6 k* M* {& o( @ {) J9 j1 C, C# R; H J
int p=a[i][j]-1;4 d2 Q8 W' g; p2 t. w* f Y
b[p].x=i;b[p].y=j;
4 V9 u0 \* Q' [1 n }( i- L' X9 w$ M' a4 x7 s
}
( n' [+ T9 C; v* q else{7 v5 o* \' t* r+ p$ s* S
for(i=0;i<m;i++): ?# b7 E; G' G& V3 |2 N6 W- g+ b& |
for(j=0;j<n;j++){( G2 N/ l' o" g8 \6 g; J
int p=a[j][i]-1;
3 a, P% v! E q9 f b[p].x=i;b[p].y=j; 1 [4 s$ T9 _* r7 r: Q! k( o
}
8 [2 h+ u) b! f. Z7 I4 Y }
/ v) _; f* a& L8 b! q}
. R* t1 W0 W# R3 V2 y7 c3 p }$ N# v6 c% r1 ]
; l( w4 y9 _- E2 ^; Z//分治法的主体由如下算法comp给出。
+ G$ E9 e0 a; Z$ J# `bool odd(int data)1 a/ U( O' X9 ~9 c# ]
{0 I" V. J/ `, ]$ _
if (data%2 ==0)
: f* v; I$ L( l/ A1 J {
! a$ H/ @5 f7 \+ p return false;
w' I3 T* T0 D$ o1 ]8 x }/ m5 c0 Q: ^& J/ t% o
return true;
) m- c( p Z' a6 B/ N}
* w( F) k! x3 ~5 S3 d- O; C
! T% P/ i) Q! p, D* @3 }: G+ p U& N. u" o: j
bool Knight::comp(int mm,int nn,int offx,int offy)
6 W& y9 l6 F! I7 n{. i* |7 F8 m4 T! V) o- y. ?5 [
int mm1,mm2,nn1,nn2;
0 w6 H# a+ H1 o& q: o# y4 g int x[8],y[8],p[8];6 r+ u/ o- g- k$ g+ M
if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;
0 E& x) ?# A7 P if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解. ^% B1 K ^& r! `6 T
mm1=mm/2;
* z( ~9 _+ b6 C# y9 e if(mm%4<0)mm1--;# a4 _0 }0 }% v6 X7 S5 R6 o* x, {
mm2=mm-mm1;, z2 S4 c' @3 D' I1 t
nn1=nn/2;+ }! D" v. B4 ]
if(nn%4>0)nn1--;# z- D; l9 E$ z3 S2 w) z
nn2=nn-nn1;1 a f) E& E5 Z& |, |2 {
//分割步 d- {7 h5 R: Z* S
comp(mm1,nn1,offx,offy);1 ^2 r: ^5 r) F- h* y$ K
comp(mm1,nn2,offx,offy+nn1);
! q( k( X9 f/ ~( O% U5 O comp(mm2,nn1,offx+mm1,offy);0 r7 J0 S( c4 j0 M# {$ p, n+ N; r
comp(mm2,nn2,offx+mm1,offy+nn1);5 @5 O: i7 \3 S' C5 V, {
//合并步' b2 f4 N) s; M: y, o
x[0]=offx+mm1-1;y[0]=offy+nn1-3;
; ^+ d) k* h( o x[1]=x[0]-1;y[1]=y[0]+2;
3 z" a+ }& \7 Z1 u% m. C7 \5 ? x[2]=x[1]-1;y[2]=y[1]+2;
: M6 F( z- E2 l1 [ x[3]=x[2]+2;y[3]=y[2]-1;
8 \5 ~( E8 \4 f4 {) @ x[4]=x[3]+1;y[4]=y[3]+2;3 R6 m# c# S# z8 C9 u
x[5]=x[4]+1;y[5]=y[4]-2;0 i' N- @# W C9 ?
x[6]=x[5]+1;y[6]=y[5]-2; t& q) U/ S1 }$ T9 Y
x[7]=x[6]-2;y[7]=y[6]+1;
' p8 ]% ?) n/ d+ {( |* @ ; r! \5 g/ E1 K" L2 t5 A% g5 s
for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);5 c6 H% w( H( @! f% d. p: V; u
for(i=1;i<8;i+=2){0 ?7 e* I1 A1 G( Q; q
int j1=(i+1)%8,j2=(i+2)%8;$ l6 Y' r0 I4 ]: e0 E
if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];6 v& F/ ~, _/ R1 g& y
else link[x[i]][y[i]].y=p[j1];
' U q; H6 _% X9 u* Q, F if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];
2 c4 _- y9 w5 v! }2 I. v else link[x[j1]][y[j1]].y=p[i];, d7 _7 d7 z( B# ~
}
" `; n9 s9 X: j! l3 J& b return 0;
& ?4 M! n+ C* I5 u}
! F0 m* C/ r$ g3 Y+ H; v" t- g8 }) N+ \
# g! O8 K$ F) y
//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。& g9 g* m. p( a0 e9 s/ z8 ~
: g) ]6 y& ]5 ~% M* yvoid Knight::base(int mm,int nn,int offx,int offy)
/ O# }0 j( y( ?" o# |" J{6 K" y' ]/ S) }1 q8 f/ Q- m
if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);
/ G. s* a- ~* ^" d1 n/ B o* C$ H if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);
( @ f5 X1 ]5 M+ f# y. y if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);! o- l" E' D+ `8 p- R: \
if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);
; z, w- I8 A5 c4 [9 `0 X if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);; t) F; D) B8 N/ t# @0 z
if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);# ?- ~9 g) j' M) `6 q# i$ s
if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);
+ f. c2 d! t' k1 N if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);) s7 H$ c. w- O- v' S$ E
if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);
5 Y" C3 B: h M8 ]}
7 U' L8 V) N2 L+ W; K$ T
# b3 d: }" v3 U/ A- q
" I" e! I2 S4 v: w0 J# P+ t$ Q* |5 U//其实质性的构造由算法build来完成。0 U0 ~! ~- A$ j. X; P( \$ p( }8 w
$ i: b1 o* q! ^1 K6 s
void Knight::build(int m,int n,int offx,int offy,int col,grid *b)
u$ z( U- r" D! z{# t* c5 M; W& v2 ]: O9 m2 x2 @
int i,p,q,k=m*n;& Z6 ^! t3 l3 o
for(i=0;i<k;i++){
: Y! o4 J' y( S6 Z p int x1=offx+b[i].x,7 n" o$ n# Q/ n$ b
y1=offy+b[i].y,4 P# S1 w- [# @* t/ ^
x2=offx+b[(i+1)%k].x,+ u1 r9 f' Q9 A u5 K$ r
y2=offy+b[(i+1)%k].y;
: e0 i% k4 ~5 P# k$ a2 F. O# l5 U( R p=pos(x1,y1,col);q=pos(x2,y2,col);
( T+ I5 |5 i5 a, P. J8 D0 O; f link[x1][y1].x=q;link[x2][y2].y=p;
; }) K7 W4 p. `5 i4 H# F } " ^. p2 v* m* }8 S* [
}: w0 {, \) k6 Y
" G/ l6 o: G) h9 }* }2 S* c2 ?, e$ a& y1 A8 F
//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.' x: r$ m, E) L5 [( |3 @7 r4 N
+ v) d- R; y" G5 S9 w( eint Knight::pos(int x,int y,int col)7 Q, t5 X. T0 t# T, J6 ]! O9 Y1 x4 y
{9 {/ A T$ x% Z
return col*x|y;
$ R7 N! z9 E2 `+ G+ ~2 P; g}
$ ?: O$ B a$ F) ^& J0 v- m+ J. |9 m, ]" I" `( M2 @3 c2 z5 j
: ?4 m' z& r5 x/ x8 Q' j8 B
//最后,由out按照要求输出计算出的结构化Hamilton回路。# Z, }4 E/ k- d; } o; S) x: I
& O: d' m7 m9 \6 S# _9 C
void Knight: ut()3 J; s" [+ _' b" x
{
% [2 u& K& ?+ |/ o int i,j,k,x,y,p,**a;: \: ^1 r% I8 C- g6 Y8 z
Make2DArray(a,m,n);1 g; D( w+ p7 |) e/ L3 N
if(comp(m,n,0,0)) return;$ \/ } t2 P+ P, T
for(i=0;i<m;i++)7 n% S8 L6 g1 Z6 X" K
for(j=0;j<n;j++) a[i][j]=0;/ {% A1 a# N- D' O/ c
i=0;j=0;k=2;a[0][0]=1;0 w+ O& D- n1 z! E3 I
cout<<"(0,0)"<<"";
0 C5 y# c7 }% D! F1 S for(p=1;p<m*n;p++){& t1 n; g* v0 w- y2 n k
x=link[i][j].x;y=link[i][j].y;; @6 M9 y) m4 m5 g+ F8 o% z
i=x/n;j=k%n;) L/ g. p! I- N% O
if(a[i][j]>0){i=y/n;j=y%n;}
5 U1 P* a4 D' o a[i][j]=k++;3 E- ^6 W8 q5 e; L8 }1 Z' M, U
cout<<"("<<i<<","<<j<<")";
. }, q U a2 ]/ I if((k-1)%n==0) cout<<endl;. M0 H7 U2 j9 M6 O
}% f4 r8 C. i8 W
cout<<endl;+ P! V3 V7 y6 B+ C0 l
for(i=0;i<m;i++){: r" t+ o4 }, L" I
for(j=0;j<n;j++) cout<<a[i][j]<<""; e5 u, b+ [( @# b0 [, o. y
cout<<endl;* @/ `7 G3 c5 b1 f' M4 I& n
}
* U5 n& w/ v1 \8 {& O} |
|