- 在线时间
- 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:3940376689 E5 e3 ~, W0 p! ^/ d/ c8 g
) w' r! s1 B2 Q; D Hamilton周游路线问题9 r& h4 |: i- n$ @( V5 |9 i5 q
2 Z( y: f7 [( l! H- Z
8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。. q2 d* |) z K3 v9 K; M
: a! e0 F+ Y B7 o* i对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
( r4 B* j) t5 W* N7 h3 R, @/ ]4 P9 r# D+ ?! k& V$ N
, o' [5 R3 a! D* d2 T
5 v3 m. i% g1 K" U& X6 K( K' ^
//算法实现:
9 r# c- c; U7 l5 q$ i) w" X* M! `- l: T I5 L. ?+ t4 a
#include <iostream>; O$ X/ r" k( o7 ]6 Q
#include <fstream>3 \. N& v( [3 c1 H7 f4 A, ]
#include <stdlib.h>
K1 Y) W; O# A* X- @" n#include <afxtempl.h> ) K# L0 G* e; o# d) \
using namespace std;( c, t! b) F( m7 L; ? W: p
template<class T>. L# W& ~. V: Y" u7 X4 D# C" w
5 p& U i6 \& O7 Jvoid Make2DArray(T** &x , int rows , int cols )
% J" N5 A0 r$ `4 x) @) S/ ], Q{ , c' e8 Y& u6 C( |' o
//创建行指针 : l7 n+ k& m. }+ v+ |' `7 G, s
x = new T*[rows] ; 8 O6 Z' G0 E/ _. i5 l
//为每一行分配空间
4 n! J1 u! t+ t4 }% O for( int i= 0 ; i<rows; i++ ) 0 L9 I0 O/ d% Y& X/ Z0 T
{ # R1 c8 f# z, f; C- s
x[i] = new int[cols] ; 4 A5 `( E( K& _0 E, W
}
, T9 x8 l8 G3 @9 o} 0 |" K# `: ~2 ~$ t5 G; }5 ~" I
template<class T>5 l' R$ B2 s. o, v/ I: Z! _
# H) t4 t( `; S
void Delete2DArray(T** &x , int rows)
3 u6 g" T( j i# {2 p, C{
. f# B( E# U: L. K1 W5 ? //释放为每一行所分配的空间
7 ^" E' v. |$ | for( int i = 0 ; i < rows ; i++ ) ) M% d: V U. q2 z; A& \
{
% ^# c& L' D0 b; h, s; p% A delete[] x[i] ;
~3 T4 b' N. G r0 b3 W7 w% V }
2 @* n- P- U$ Q3 y0 g // 释放行指针 1 j5 _& A% }9 N9 p$ K
delete[] x ; 5 n, \1 v Y- p+ Y
x = 0 ;
6 l* }: i" L4 J& P; O4 t& y' D1 ^- x}. Q/ N1 Y3 e2 C
& I: O8 L# O% l7 g9 W
//其中,grid是表示整数对的结构。
6 K0 c* V, K* U6 w. Utypedef struct
/ Q @% X, @* m8 y, ~% T2 j{
% x$ Q# k, m* ?& r& B- `; G: O int x;
6 ]1 u4 L* Y) t1 g9 Q1 B) S3 o int y;
! w9 ?" q; O# X5 G}grid;
' E/ ?- ?0 f4 ^+ @; I3 W6 ^
4 D, J* a- }3 o5 L, v//用一个类Knight实现算法。' s& b0 H! C! e; a/ H
6 {) c a# ^% c" \- _0 C: \
; ~' h1 m0 g0 r. t6 D" R5 {
class Knight
. F/ h+ F4 j! d' N* V* M4 M{' s: u/ Z1 ~( k, B2 g% v
public:
! y) b1 R, N. ?. [) ], s1 h Knight(int m,int n);( @* a) e9 a( n+ o
~Knight(){};
% N, K* W/ N+ M6 Z. }0 t$ W! P+ c+ E0 r" E void out();
. f5 d* g% \- h `" D; @private:
$ M0 q2 r7 n" U int m,n;
9 e# A' t, \* v grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;
$ j9 K1 W. f/ F w( b int pos(int x,int y,int col);
. B1 S. q, w4 n: H0 Y a2 s" i; h# p void step(int m,int n,int **a,grid *b);
4 s+ m3 A1 s( G2 B# u1 q void build(int m,int n,int offx,int offy,int col,grid *b);4 N0 ~- ~6 {! [3 f
void base(int mm,int nn,int offx,int offy);9 V4 v }8 s, \# d% s1 M& q8 c' ~& ~" z+ t
bool comp(int mm,int nn,int offx,int offy );! C' D7 [- Z. W+ N- @5 H
};
, l; E1 ^ T) V
- A7 k N3 U' s; |* B. i ! G# |! U( a, J% A" G6 v
9 m- ~/ A+ a3 g6 \/ R! T: E& G+ A7 m0 g5 u- n7 J
//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。
1 K7 I4 P" b' s! v//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回路。
$ J0 u) o- @1 I# {6 f+ E5 \! z* }& r! @* w" S
! l5 U V) j$ Q9 G Z& N9 T
//构造函数读入基础数据,初始化各数组。! u1 \* \! t" I
) ^+ ?3 h" f8 g6 C; f
Knight::Knight(int mm,int nn)3 G2 U2 F9 w- [1 j
{$ o; F; Q: o" N a- C2 {, H
int i,j,**a;
! _( O+ H5 V, | ifstream fin0;, \& b9 |! d& R8 q' @5 E
m=mm;n=nn;
2 p* d: R e" F b66=new grid[36];4 u2 U2 v' E' n
b68=new grid[48];2 H1 i |, k; C9 K% [% p
b86=new grid[48];: X { W- ?6 I" q" ~ P: _$ T
b88=new grid[64];9 C+ T: ^+ b, K- z" A. Q
b810=new grid[80];
/ Q" Y; B3 Y, n! B4 D# M1 [ b108=new grid[80];, a) p, k2 i8 }4 l1 p( y+ e, d
b1010=new grid[100];8 F2 R* s* o: _( N6 k( A0 l2 q
b1012=new grid[120];
: Q# Z3 l, o6 u, A b1210=new grid[120];
/ K, p+ ]3 Y! W6 t5 { Make2DArray(link,m,n);: V; }' L7 R5 O7 i w+ K
Make2DArray(a,10,12); ~$ c3 l0 G/ ~# L
2 ~$ }6 k; d0 q ~" O! ?8 t0 A for(i=0;i<6;i++)
$ A/ F" ]( ?9 ~( k4 q) [ for(j=0;j<6;j++) 1 G% v2 c, B# p& W7 `
fin0>>a[i][j];
# W$ i& q* v( o9 S& |+ Z j step(6,6,a,b66);
+ [: H0 F3 B+ `7 k for(i=0;i<6;i++)+ I/ I: L5 m- E z5 I
for(j=0;j<8;j++)
, ?7 b7 D- O0 |8 f fin0>>a[i][j];5 o, [; j% C& o: _- v/ Q; O
step(6,8,a,b68);
5 w7 V: W( O7 G/ z step(8,6,a,b86);
! g5 W5 o9 E1 r; @4 k1 J# f8 z: @ for(i=0;i<8;i++)2 ]% E0 v0 K* l& n1 `; t! p# i
for(j=0;j<8;j++)
9 i" ]7 v+ Z8 ^: \8 n5 f fin0>>a[i][j];( J, k1 _9 M, P" q2 e! _
step(8,8,a,b88);" u5 S) p7 d! K
for(i=0;i<8;i++)1 Y! I% U6 k R3 ~9 _9 {% K
for(j=0;j<10;j++)
& l! H [! `# v9 M" ]! ]! y t4 T fin0>>a[i][j];
! w: [9 U2 j3 T- w% S step(8,10,a,b810);9 g0 p9 h, n: `
step(10,8,a,b108);
% p" m2 L5 L# A for(i=0;i<10;i++)
' p; \0 l: Q' _. n for(j=0;j<10;j++) % \( I0 o/ \% P& i7 ]
fin0>>a[i][j];) W4 s9 D* h( |( k$ S- X
step(10,10,a,b1010);
/ o7 {2 T# K/ F* l; p8 w* `- q for(i=0;i<10;i++)
* \/ }$ S& U7 }' s' _! K for(j=0;j<12;j++) ! X) m5 X# l' f2 D/ V3 J
fin0>>a[i][j];
7 L8 h2 g$ T/ R1 J& q4 ~0 I step(10,12,a,b1012);% s7 ?& v5 \$ [6 m
step(12,10,a,b1210);# b4 P2 }5 X" h t/ `
! N* O) Z/ k( E. h( z: g8 Y; N}7 c4 D; `5 t# m( M0 }9 ^( l
6 O+ w2 I* f, s& [7 H! N
( F( p V& v# q, p8 e6 s( `- v
//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。4 f/ k8 m# O& A
' k/ }* S0 U( m# d# ^8 xvoid Knight::step(int m,int n,int **a,grid *b)
/ T% w, @4 V/ G1 g$ o{
0 |) ^1 g8 Y/ ^5 g# y5 d, J3 U int i,j,k=m*n;
/ e- D9 Y) z& g- x$ k; T if(m<n)
! J+ E% _6 \. V {: P7 M7 r9 [1 F' s- j
for(i=0;i<m;i++)/ [ U/ \* c9 f' G& ~5 m$ T( T
for(j=0;j<n;j++)1 H* F( D" P8 D
{
5 f3 W* w/ m' w& {1 S- t int p=a[i][j]-1;2 _& q0 W: @8 i& l) h
b[p].x=i;b[p].y=j;: F& }; d% K( r/ u4 P- \
}
& K: ]3 X, p2 r4 m- ` }
# z& w. n& z: \4 n# ` else{
/ Q' L% X+ F! [5 `; J/ T4 f$ q2 N for(i=0;i<m;i++) U& \0 E" ]( r! {6 V
for(j=0;j<n;j++){; B- m1 y% E; [# e" q, \
int p=a[j][i]-1;
$ E% `- [$ W8 M5 Q b[p].x=i;b[p].y=j; - f% d# z, l. a( Y5 Z
}
6 C% X, j, t0 D+ N }1 [, O# A9 z9 F* b* m; _3 B
}
! f- d1 j( `% m9 Q/ I. ~
: P2 V5 l3 S1 e8 [. O" w. q3 c/ E$ L
//分治法的主体由如下算法comp给出。
, u9 M1 H& ]8 n8 _0 t2 H4 f9 _bool odd(int data)
8 x6 X& _" X, T) l) A3 ^% G4 H7 e" B' w{0 p5 l8 E% h9 ?( b! r0 V1 z3 c! ]
if (data%2 ==0)
$ Q9 ^7 g: _0 F [* D5 l E {5 k, r, I! o! g9 O
return false;
, {8 V$ I, C! h) E6 Q }
+ S0 P0 w6 b: C& A, z. E: w* O return true;7 e1 D% u9 C7 `: s+ N0 I" B
}
* P4 ^; b5 M, ~1 c% u3 w n4 E; V3 f! H6 d% X* \
3 M, ]- s( _/ v) ]' [2 g
bool Knight::comp(int mm,int nn,int offx,int offy)1 n* l& Q& y5 ?2 r% n! e! f4 T
{
& X; B( l. ?, Y9 V& x int mm1,mm2,nn1,nn2;% I* J: X% j/ I& o! Z. N
int x[8],y[8],p[8];- L6 k$ [3 |* O0 s- {
if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;
+ J0 {, n2 _$ c0 A2 `5 |* i8 R if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解& x* j' b, A! s$ r8 e: K
mm1=mm/2;2 S. s8 W- L |6 J) }2 n
if(mm%4<0)mm1--;. w1 f8 Q/ }& c9 c3 P
mm2=mm-mm1;/ E9 o/ l+ M: R
nn1=nn/2;' @8 \6 s- S- K
if(nn%4>0)nn1--;8 [( j$ X/ x! `
nn2=nn-nn1;
$ m0 L* C/ a0 Z) { //分割步
7 [; Q2 _& y5 [ comp(mm1,nn1,offx,offy);
]$ `8 i0 n( T' P' [2 q4 ? comp(mm1,nn2,offx,offy+nn1);
$ h8 k$ y$ m8 S% O comp(mm2,nn1,offx+mm1,offy);- n7 w9 @9 W; q0 j+ O: l# G" }
comp(mm2,nn2,offx+mm1,offy+nn1);
# D9 j9 I' \4 l$ b( X' S- V //合并步% v9 K9 I$ i9 L4 K1 o6 X
x[0]=offx+mm1-1;y[0]=offy+nn1-3;9 t" k- u/ q3 \1 `: t0 _
x[1]=x[0]-1;y[1]=y[0]+2;; t/ b6 c! }; ?& H
x[2]=x[1]-1;y[2]=y[1]+2;' I' v) h W" H) y7 t: |
x[3]=x[2]+2;y[3]=y[2]-1;1 O4 [; a# z+ s- s2 C
x[4]=x[3]+1;y[4]=y[3]+2;
& G* K- ]3 A! m0 T x[5]=x[4]+1;y[5]=y[4]-2;
9 t: F; |: O. V1 p r& ~; | x[6]=x[5]+1;y[6]=y[5]-2;
6 a: g Z5 J! R+ ?- h$ }' w9 u x[7]=x[6]-2;y[7]=y[6]+1;. e/ Q8 x9 R. W ]" w: Y
) J+ G) M# d" @ m for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);
( J, L6 K/ S8 F for(i=1;i<8;i+=2){$ J9 x2 W* W- U) N, Y5 d7 n
int j1=(i+1)%8,j2=(i+2)%8;! L5 t5 U" o0 b7 p; t! b" g0 t5 E0 X
if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];
5 C3 o$ b, Y4 n1 V9 h' M. }8 d else link[x[i]][y[i]].y=p[j1];& I* m3 @& V$ ^; x- i
if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];
* r+ u" M: d: L8 Y6 a( F else link[x[j1]][y[j1]].y=p[i];; L. d$ X3 }* x/ k
}
; V r+ b4 n# m return 0;
- i, b2 J/ D' H7 J: {}
9 c1 O; I- Z* C8 W& ?) x; x0 M8 b/ D0 o* `7 j/ p8 c' }$ i* H! _
/ U1 X' U/ ` s) _: W! q
//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。9 ?3 h4 M* F# R; D. n' n9 U
8 a( G9 X2 o8 G$ P* Vvoid Knight::base(int mm,int nn,int offx,int offy)# v2 [5 X0 {# E k0 }: a
{
* k$ c; c: _' R, B6 z3 i2 X if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);
, c, x2 ^3 P& t. h6 J N if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);
, g9 p% P( k& L. j/ Y$ o if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);. ^7 w# K* { k
if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);
( b2 ^3 O* G* ]' ]9 x if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);$ `5 Y2 v8 w0 N/ V* G
if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);
7 C/ {8 S" ]2 U if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);
2 c/ \8 S, M0 o- r x3 ` if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);
. `7 `+ T2 `9 X) Z3 n' F if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);
) c3 ?* R, `+ S: I3 [8 A, N}: V s1 Q9 [. _9 Q% M( m
: s+ y. k2 K6 g; b
) T8 U/ u, |1 \2 z//其实质性的构造由算法build来完成。
' B2 Z; d6 O3 t: h% l
! r# F1 ]# P& T" F' }: D4 Xvoid Knight::build(int m,int n,int offx,int offy,int col,grid *b)+ |4 j- u4 d. Y c6 [3 H1 k
{3 v6 I3 g8 a/ v$ X% H
int i,p,q,k=m*n;
% X6 a4 \- ~- M- Z& h for(i=0;i<k;i++){- i, u; O/ _- e/ O
int x1=offx+b[i].x,
2 _/ m! Q( D' l y1=offy+b[i].y,
3 x, n0 `$ v3 l7 N# U x2=offx+b[(i+1)%k].x,
4 T) D( c$ f' X4 f$ C: Z( l. v y2=offy+b[(i+1)%k].y;
$ {4 D+ Y2 H9 ` N; v p=pos(x1,y1,col);q=pos(x2,y2,col);
5 z2 ^6 |$ p. V link[x1][y1].x=q;link[x2][y2].y=p;
) T& A1 @ [2 r" _8 o/ y8 A; ^& L } 4 t& C) F. e: \; h* n
}% [% w0 g1 k9 I
2 Y, |/ V( j0 l4 ^' q, u9 A8 r) ~# f& q7 X; c' O3 y9 Z* _# B
//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.# v8 Y$ |+ k0 I' T3 M
8 t7 a& m4 n6 U& _3 `
int Knight::pos(int x,int y,int col)
* h2 f3 r" J9 M" |& e$ E- L: @{ R+ A+ J8 A8 o$ I: ]
return col*x|y;
6 `0 W, \7 v! h( O/ S}) Z9 U7 S6 C% S3 n2 W* y
# ?7 v# A2 ?* _) {5 L, }' d5 ~7 H p/ b
//最后,由out按照要求输出计算出的结构化Hamilton回路。& I2 \, D% R% v3 ~ Z" u# p8 B) {
7 J: B/ }8 M* b a2 Uvoid Knight: ut()% ^* x w# T8 q! K4 B
{6 n6 H T" R! w! S" Z3 D. y
int i,j,k,x,y,p,**a;
8 Q! s$ `1 ~$ w Make2DArray(a,m,n);
( q- q2 W2 e. O% \$ W if(comp(m,n,0,0)) return;: g! z4 `" {9 n& N: G0 {. x5 d
for(i=0;i<m;i++)
+ d3 v# r4 P* K' V) Q+ u for(j=0;j<n;j++) a[i][j]=0;$ R7 y9 d. a% g; b$ x( J
i=0;j=0;k=2;a[0][0]=1; o9 W% o% I, I3 g' |" V
cout<<"(0,0)"<<"";5 m- p4 M2 E# v4 o( @) N
for(p=1;p<m*n;p++){; Z0 n* c! A2 \* Z" Z) L
x=link[i][j].x;y=link[i][j].y;
! e' p! x) P+ Z1 A i=x/n;j=k%n;; g. @- k$ _3 L
if(a[i][j]>0){i=y/n;j=y%n;} I' q9 [6 M) f# l, f9 \' o G8 e" F
a[i][j]=k++;
( l. ~' M7 ~0 O, { cout<<"("<<i<<","<<j<<")";
+ l0 T" }( R9 o3 _$ O+ t if((k-1)%n==0) cout<<endl;
5 \/ K3 o5 M C i! b4 _ }
7 T2 c: ], v$ P+ H% \/ m7 i cout<<endl;
2 u+ G* g! O% ^8 [; V: v for(i=0;i<m;i++){
& E" K! _) O: o( \. \5 ^ for(j=0;j<n;j++) cout<<a[i][j]<<"";$ n. m& E4 [" |) ^" C
cout<<endl;
5 v! Y5 a; i- P+ O& m }; A7 o' G, D) o9 C; o0 |
} |
|