- 在线时间
- 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
' m3 y1 ]+ o6 w8 u: L- O x& K0 F+ \7 r1 @; n
Hamilton周游路线问题4 D9 K3 y- ~5 z) c2 w- t; _
?& L4 k! r" z
8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。4 ~7 J0 e5 }9 u, w" ^
+ M9 N) ~$ j6 a+ M$ Z! X
对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
- e- s( h9 q- g- M5 n7 W0 U
0 L; v/ ~& i7 v8 H
9 t& y9 o' H6 a/ s5 b
+ {9 M) A, A a% d0 R//算法实现:; v8 n4 o' g! M# B% X
5 ]1 N2 s) x4 g) u' v8 ?#include <iostream>8 k6 x, _" f: e3 h3 J
#include <fstream>2 P. ~5 \5 ]# m8 K
#include <stdlib.h>
8 q. f' _0 _& ^( y( d' g: L# K#include <afxtempl.h>
/ U1 r o1 B/ ?) z2 I- uusing namespace std;. n8 |9 ~8 c+ X+ Y9 E8 N8 J
template<class T>
W3 p0 ?( \. P" T* B" \( Q
% Z( c+ d" i% w4 svoid Make2DArray(T** &x , int rows , int cols ) $ \# s1 `3 H. h! g! y
{ 8 j; k$ J; O0 \( w0 r' |% i9 X
//创建行指针 . g4 r0 B2 w' k* w) I. H
x = new T*[rows] ;
0 l7 g9 [/ t! X) y0 t //为每一行分配空间
8 f4 h( p6 H; W: n( q3 W- | for( int i= 0 ; i<rows; i++ )
2 r* I2 N/ d9 s! W { # ]& D9 e$ K4 F& g- @' u9 {
x[i] = new int[cols] ; + N, L- }: c: H$ r
} E' q; x* m4 ?! n
} ! L, ?3 G8 w$ k
template<class T>
/ C2 z3 l+ {% O: \/ ^5 j+ L; s: o6 U j! k
void Delete2DArray(T** &x , int rows)
; y9 x1 c' L1 Y j* a{
: T& C5 [- _# Q( G9 T2 p! t //释放为每一行所分配的空间
% B# L; E6 A8 a9 Z' F7 O7 C% P for( int i = 0 ; i < rows ; i++ )
/ V0 K8 p/ M% P {
/ A$ C5 o+ \' ~( K0 M2 Q delete[] x[i] ;
) [! W$ ^) K* n } 6 b* T$ N' H/ T6 C( o2 ?
// 释放行指针 ( n- O' N L) J, Q" K
delete[] x ; % i6 Q5 ~6 p) `
x = 0 ;
3 g: Y/ t$ P; @# i/ a& m! i5 }}! u# z0 i% ~4 _9 n
4 T9 V: H1 r6 v//其中,grid是表示整数对的结构。
2 V' Q, g2 `5 W4 ?' t( `5 s) y4 dtypedef struct
4 W u/ E( W" ~6 m$ k{
6 l2 A. o5 T9 b$ f p int x;
9 a% h6 ?9 s+ e- W/ z) j int y;
+ y! [, s3 F- u: ~}grid;7 V( g. a9 X) I9 n% B7 v7 s; U
9 `, |3 [+ `! d5 ^
//用一个类Knight实现算法。6 L0 T" Y2 z4 I
& l# X9 {) Q0 u( g. P
5 ~% i6 H) P( h2 lclass Knight2 j4 B3 Q7 l) e2 f( Y
{
7 u% c% a6 n6 Z' C9 C& tpublic:$ i4 E: z7 t7 ~" r! v. n, q
Knight(int m,int n);
. b- b& S* q- E+ `: k ~Knight(){};9 p2 | e$ x- J( k1 q% }; ?- }2 q
void out();
- u' O" G( f1 I- L" kprivate:
) P+ F3 q$ ^/ f! y, ]1 M0 w6 j5 j int m,n;
/ i# ?: Q: E% `9 a& D grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;
- ~9 { B% H, ^8 [" s! x int pos(int x,int y,int col);( B0 j$ k* ?4 q; b* U) d
void step(int m,int n,int **a,grid *b);2 z2 j9 ]2 I9 E+ u: o0 ?- l
void build(int m,int n,int offx,int offy,int col,grid *b);& I7 Y7 b( X: n3 H
void base(int mm,int nn,int offx,int offy);5 Z& [+ @0 M5 V: b7 C O
bool comp(int mm,int nn,int offx,int offy );8 ?; I2 j. P: j$ s
};
+ Y- x. c) F9 y. W' M. l) g3 i6 N- y9 ^+ l' A8 o
4 o, j8 Y* q; w# r+ c0 X
) J [, W7 S- J/ ~/ U( J* p' S; I6 z# W _. S, ^2 O' B' e a- D
//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。
+ A8 D' b5 Y8 B8 S0 k//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回路。6 Q' Y( f+ [9 @; `
2 E9 ` l. c7 @3 i" O/ Z. n z E4 \! ~
& p0 }& w4 j8 p- q. X3 {* c: `4 k5 O//构造函数读入基础数据,初始化各数组。; _9 w% p T2 F5 q
S, [6 R. v- E( O% F
Knight::Knight(int mm,int nn)
+ _, u1 J3 H2 x, T{0 @9 r2 X8 `6 R0 N5 ^% _
int i,j,**a;
% _3 J# C; g3 L; O! i9 V; R; I ifstream fin0;
+ b: f8 Q2 e7 F m=mm;n=nn;1 z2 v3 y9 }7 U9 M7 c1 F2 O4 X
b66=new grid[36];1 ^" A0 I4 c8 m( o7 a
b68=new grid[48]; N6 M' X- T- o& `, W% ~1 G
b86=new grid[48];
+ {& {6 B0 |! G b88=new grid[64];
/ c* o. r( C9 c3 d( \$ z7 F& ~ b810=new grid[80];
# q% I* Q% x8 n( ?: J b108=new grid[80];
/ F$ c% C W6 k& L b1010=new grid[100];. p/ R7 t. E: u: X5 `) q& s
b1012=new grid[120];
/ E5 W! s$ V- \+ e. \ b1210=new grid[120];7 d1 |: F9 Q6 U# a, r8 a
Make2DArray(link,m,n);
# C8 C+ z ^2 h Make2DArray(a,10,12);
4 b' n* J8 W; _& D4 A% h, h& J $ U9 O1 ?9 \* b
for(i=0;i<6;i++)
5 p" a. L' E- P$ e for(j=0;j<6;j++) - T3 W3 c: h3 n* I& |6 h% C
fin0>>a[i][j];
! c' f3 Z0 Y$ [ step(6,6,a,b66);
. v( S: c. w6 U/ k) [5 l3 P for(i=0;i<6;i++)& d3 L# U2 d9 o5 a
for(j=0;j<8;j++)
I% Y l4 F% ]- ~) ?. t fin0>>a[i][j];% m1 l& I$ f7 \4 ]
step(6,8,a,b68);6 `. s; J- w( y" I
step(8,6,a,b86);& q: }) U! H! |, Z. {' x
for(i=0;i<8;i++)9 @: U% T) S. R* W
for(j=0;j<8;j++)
, L: X! |& V) J4 `0 s fin0>>a[i][j];2 @: ? u) t! q, t
step(8,8,a,b88);
/ e [3 H- ~3 A' A' ~ for(i=0;i<8;i++)
+ P5 ]0 l6 b" d) A( p& }! u for(j=0;j<10;j++) 0 \- ?4 B; D5 e. A) G
fin0>>a[i][j];
1 E" _9 b1 g$ v4 N' Y step(8,10,a,b810);
+ B% W, H- ]" Y7 u step(10,8,a,b108);
1 P) U3 |6 m" }9 e for(i=0;i<10;i++)' C R a+ B' l9 N
for(j=0;j<10;j++) ' V+ q) {6 r! O8 ]% @* H# Q6 r/ X
fin0>>a[i][j];
. J" n) Q! @0 Z! f5 `: j9 _ step(10,10,a,b1010);5 ?3 Z: `" y6 H y
for(i=0;i<10;i++)
( |5 h/ [7 z1 v% | for(j=0;j<12;j++)
" V! h8 \% O8 S0 Y8 V fin0>>a[i][j];
" Z: `8 |. A' `. z R7 T2 p step(10,12,a,b1012);/ A8 a& w! h2 y0 Z# h) U; {/ o$ b
step(12,10,a,b1210);8 Q5 L8 Y- e& N/ H: |$ g _0 Z: i
4 [# M1 R1 C8 M/ ^( h3 s$ N
}) H1 G) [# m/ M: A1 n {
, G4 _7 N2 B2 A& `, N2 B+ A" F
, d6 ?2 B5 t4 ~2 O
//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。
/ h9 Z- o& M, R$ u5 |
% M& V( ? ^/ K" Yvoid Knight::step(int m,int n,int **a,grid *b)9 @/ f: A5 L& }1 h Y
{/ X' S; Z+ t/ g2 P! }& ]' N1 ^1 x
int i,j,k=m*n;
8 I" ^: @* H" f6 {- d2 L" s if(m<n)2 o. C: W7 l- B. f% Y7 u2 X- a3 j
{
+ T/ v8 A9 o* m- _3 T8 w for(i=0;i<m;i++)% h2 I* ?: ]7 t* B( Y
for(j=0;j<n;j++)0 Y# y/ A2 }2 H t9 C
{- ?$ e0 E, z7 ]6 |
int p=a[i][j]-1;
c ~: b, j7 k+ D. z: v# l9 T b[p].x=i;b[p].y=j;
: M e5 J8 c/ c1 c/ f1 C4 u3 y }, W2 |, u- P3 [
} `- q9 [- u* O2 Q4 K( ^
else{* v* d& f. c+ O: h7 X
for(i=0;i<m;i++)" f0 X- |) o# I( ^3 B& R5 S8 f
for(j=0;j<n;j++){/ Z% m# l) Y- q5 ?5 K
int p=a[j][i]-1;2 u x7 G. n8 j9 Y5 ?! Q8 O
b[p].x=i;b[p].y=j; 7 V2 ^- m% n) e+ X6 `! G
}
5 Z$ A" {6 e( h J1 p5 q1 h4 t6 G }
6 r+ L5 b5 ?+ G( U- p- A3 M}7 g0 ^) z9 ?/ T* f5 X
) Z$ u+ h, k3 ~9 D
8 o1 o! b2 L$ y5 S% F) |//分治法的主体由如下算法comp给出。
; r, S" Z2 ?% K3 W- d$ gbool odd(int data)0 r$ s% v, ^/ m
{
' f- G# a) v) z. b- R5 { if (data%2 ==0)
* N& b4 O1 T" P. r {- u, l! W" k+ \& S* ~: x
return false;
) v- I( Z7 b' u+ E1 o# ]: W }
/ C# {& \! ]: o& C7 h% \ return true;
" ?7 |) s: c4 o5 ~}
0 `1 N& R: @4 _) G8 e! n1 j! q( `
* [4 w+ ]9 S/ m+ ~7 l, \" _/ U* y8 W4 Q; ]
bool Knight::comp(int mm,int nn,int offx,int offy)
1 o" I$ V2 |; k& S$ L. H! _& g{
$ k2 ?9 D" K' L! c# Q( v) m int mm1,mm2,nn1,nn2;
) k. l5 c- ~! d8 R( g' T int x[8],y[8],p[8];& P2 Q- D2 [+ h6 k/ [
if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;
, U8 p% b) l R if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解
. _2 V! Z7 V# @* B mm1=mm/2;
' O+ T N0 ^# S7 Z if(mm%4<0)mm1--; V5 \" D9 K: F/ O4 z u8 K1 k! E
mm2=mm-mm1;
& P. A0 T( w* [ nn1=nn/2;1 m' W' H5 a" l9 M2 A- }/ X
if(nn%4>0)nn1--;/ p& m: Y. W4 _
nn2=nn-nn1;6 z$ ?2 T8 V# {! X- f$ L2 S1 Q1 F
//分割步0 C2 n$ B# a' `5 `8 m6 k# Z' D/ f
comp(mm1,nn1,offx,offy); W% @0 _7 k- z. Y! w9 K d
comp(mm1,nn2,offx,offy+nn1);
( l: R; n; F8 s) t comp(mm2,nn1,offx+mm1,offy);
9 M% D9 f+ i4 R& ?1 h% R' M comp(mm2,nn2,offx+mm1,offy+nn1); q. c5 ^/ z8 O ?2 D0 X
//合并步
. l( j% p( |( A) l* R5 ^ x[0]=offx+mm1-1;y[0]=offy+nn1-3;
; n& k6 G* S9 f& x) L x[1]=x[0]-1;y[1]=y[0]+2;" M% B2 G" Q% t# e6 S( A) R
x[2]=x[1]-1;y[2]=y[1]+2;
& g0 E7 w: ^7 [, c T+ A: P3 m0 _0 R; L x[3]=x[2]+2;y[3]=y[2]-1;- u7 O) j/ k3 ]6 _) F) Y3 K
x[4]=x[3]+1;y[4]=y[3]+2;+ d( n$ w1 r9 K6 D. W7 }0 q( |8 Q. _$ }
x[5]=x[4]+1;y[5]=y[4]-2;8 H7 V8 _% L3 s: O9 T; V
x[6]=x[5]+1;y[6]=y[5]-2;
& ?0 f# v; S8 G x[7]=x[6]-2;y[7]=y[6]+1;, K5 K0 x G8 ~( s
- V4 j& k& o- H; f for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);
1 f* B: W5 U5 u for(i=1;i<8;i+=2){! ^. t1 j" q4 r/ X+ W9 t
int j1=(i+1)%8,j2=(i+2)%8;6 P' E0 I- Z9 i
if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];
& S$ w3 N2 \& k/ G$ s: N6 B else link[x[i]][y[i]].y=p[j1];- A5 q" X, ^( C# Y2 J2 x* K
if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];
5 F5 n) F, u7 s( H& `1 @ else link[x[j1]][y[j1]].y=p[i];! b0 v0 y; \# }' d9 e
}4 N3 R5 J2 Z& ?
return 0;9 G5 s3 O1 N3 b' _# a9 @
}; K+ b; ~8 J; a# W. g1 _/ x: E
4 x: m6 d' P. N
' d) p' [6 i4 E6 V; q/ D//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。+ q' J! F5 [9 l, m7 B
* d8 N% k( T- b' e' svoid Knight::base(int mm,int nn,int offx,int offy)& T5 w6 Y: }/ l' j$ k1 e6 @
{
/ ?6 G: p) Q0 {+ k if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);
+ t3 r$ k" N1 @0 _' g) c6 h if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);- D$ L3 O# w! J' d+ A
if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);
# r2 g5 V' l# N( U, Y& H- z& r7 k if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);
- g# W* b5 N* U9 F$ c7 s if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);4 J. T8 e; \ h$ f Z5 i+ H- \8 O
if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);
, t. D, F2 g7 o. T if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);
2 g, { A" H5 O% i if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);8 d7 ~0 g9 u* }+ ~* n
if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);) B9 L# ? e2 O- n0 F* R/ g: a
}& l0 _# m/ y. \7 ~7 Q- K" ^3 w
$ i/ d# J7 M% N9 U8 Q
8 q3 [; G7 q9 X6 F! C! C
//其实质性的构造由算法build来完成。7 ~- y& C" C1 r1 F4 l( H
; c- e. ^$ P9 y, V; M4 I7 [9 L
void Knight::build(int m,int n,int offx,int offy,int col,grid *b)4 X6 C# P* `; W0 f! W/ a' ~, \+ P
{6 y! [0 ?+ Z" x* W1 V
int i,p,q,k=m*n;& T. k2 P! ~; e1 g3 U7 d7 S0 h9 r
for(i=0;i<k;i++){; D; K8 r! j) [ h( [9 A7 J
int x1=offx+b[i].x,! R8 M9 c( O. E* A$ S
y1=offy+b[i].y,0 P2 f7 F x6 V: s5 _0 ]0 ?- Q4 A
x2=offx+b[(i+1)%k].x,/ ?' M, l7 B7 ^' b6 r+ e* y! g7 M' h
y2=offy+b[(i+1)%k].y;8 d6 A& n5 `9 I& |" }3 H3 i
p=pos(x1,y1,col);q=pos(x2,y2,col);; r' O$ Q, h6 ?9 I6 c
link[x1][y1].x=q;link[x2][y2].y=p;
1 [. O( m2 Q6 b* f }
% r T5 O/ O0 K" d}9 t, Z" w! N7 u# ^& R% {
+ l9 l. @2 i0 ^1 W$ `" z- B4 ?' K) i$ h/ l/ o0 S
//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.2 _8 @: Y: R: T, V
2 U) Z/ R! r. p; W. X3 X* `& E/ z8 y
int Knight::pos(int x,int y,int col)4 p" {% I) Y D7 A( X' Z
{7 @4 v/ n, S3 Z( i$ M3 {1 V
return col*x|y;$ R% q6 \) w$ `, Z4 h) a. w# K
}& w' o; J& `+ Q$ ?6 f6 z r
5 \, E% n h5 q- m( Z2 G
' F+ c/ h, N4 ~; \ h% n9 N
//最后,由out按照要求输出计算出的结构化Hamilton回路。6 c/ E* o9 O% m( w& h
7 O$ W" \8 E5 p9 T/ ~5 N! h7 gvoid Knight: ut()
* s" M N" m7 l{
" O6 g7 j1 M! f/ B; p% k" P- ] q" o( @ int i,j,k,x,y,p,**a;
+ ?9 h9 u; O9 o5 F7 S6 I p# J) W5 _ Make2DArray(a,m,n);, v, a( U( P5 P0 P
if(comp(m,n,0,0)) return;
( s/ q: h5 R. Q* y, [1 @* Q6 g for(i=0;i<m;i++)* H+ N5 z7 r5 X' Q8 E! d
for(j=0;j<n;j++) a[i][j]=0;0 T$ w* y0 P# M% h
i=0;j=0;k=2;a[0][0]=1;$ G# I( l z% H! H- o* J0 R4 v6 f& x
cout<<"(0,0)"<<"";
5 r* u+ P* y4 D; B( M for(p=1;p<m*n;p++){
& K( v7 M% x& {! o6 k/ [ x=link[i][j].x;y=link[i][j].y;. z7 v8 `9 R, n! j7 A1 A
i=x/n;j=k%n;4 v/ ^* U h$ ?* G
if(a[i][j]>0){i=y/n;j=y%n;}
6 m: Q& w9 j# P; [ a[i][j]=k++;
c! r* V b. S+ C cout<<"("<<i<<","<<j<<")";1 k# o3 a7 u* s
if((k-1)%n==0) cout<<endl;: i( `* p4 r2 n1 r
}
7 z, ^# X" |1 ~' J+ f8 C/ J: z cout<<endl;4 D( r! N& f. i( S; ]
for(i=0;i<m;i++){
1 {* g" H# j- @( d5 k3 L# S3 @ for(j=0;j<n;j++) cout<<a[i][j]<<"";
. m ^, d- g) G, f/ u cout<<endl;& M& m; g' d; O2 g
}
1 h+ L# |+ H) d: T: \. o} |
|