- 在线时间
- 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
: C( l' T: Z% r6 J
$ J7 U) ^) x/ r( H& l Hamilton周游路线问题
) C% v$ [& r' ~3 H% J3 A4 C7 @* @5 R1 J4 G0 `3 p, k
8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。
6 P. B5 v q" d! z5 l+ I
c/ u7 ~+ R4 z1 ^$ \/ t3 O对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
, s9 `8 [% k( k( G, R A
% i4 w2 A& P" T) D) T# r; J" m8 z* [5 Q8 S: c( W
1 ? J& }& x4 B. i* O( G, r
//算法实现:9 H( ^4 U3 x$ Z0 e( `
3 H( ]4 E- e) ]' L8 l
#include <iostream>& Z- q0 L. _2 V4 j% p
#include <fstream>9 ~2 W, `9 [1 P+ a) y- k
#include <stdlib.h>
1 }6 P6 a& h2 S0 l4 Z; r8 f#include <afxtempl.h> 4 [7 b) c' q/ O
using namespace std;* K' P8 D( O. }2 R
template<class T>8 n; J# L! d b- i
1 i% @' J \+ X4 E& C
void Make2DArray(T** &x , int rows , int cols )
" ^) X9 S3 x4 m+ \( u( P{ / g# Y$ G/ n0 R. }$ J
//创建行指针 # ~! C0 h% y7 P3 w2 ^8 Z/ a* f! [# Q
x = new T*[rows] ; / {: D' P0 a; L4 {9 {
//为每一行分配空间
2 c/ ~# \4 H$ \: q8 W5 y# z for( int i= 0 ; i<rows; i++ )
- D8 Q; P# \2 f( y& z% Q+ z {
l H+ W4 H( s x[i] = new int[cols] ;
& w V+ H) ^5 N* N0 T1 l8 Z: W, L } , R) q* C! _& [3 r
}
! d! U9 l. Y' O; q9 Jtemplate<class T>
& b5 X2 \) @' k' t
5 V( H: R3 A! a% c- \, Y bvoid Delete2DArray(T** &x , int rows) ( D5 T. ]! j; F0 O1 X: u& D) i( f
{ 1 [' v3 \8 h$ E
//释放为每一行所分配的空间 4 f6 e% F) O) T: q
for( int i = 0 ; i < rows ; i++ )
% F9 d& |) `. Y5 x$ n {
+ F2 s9 C7 E( Z# g. E delete[] x[i] ; 2 i! s+ D- g% R* I3 K/ K
} 6 ^$ {5 O3 n# \1 R- S4 k1 a
// 释放行指针
' F7 v1 A* V# W9 b5 v0 K delete[] x ;
3 r; X1 a# Q- f5 b0 Y' L# I x = 0 ;
; k. X n7 c9 z+ S$ Y; ~}' t" o4 B% C/ \# j: U1 p X* O
# v3 ?7 h; ]4 L' U//其中,grid是表示整数对的结构。
# n5 k' @2 B6 C% s' l/ g5 etypedef struct
$ z: [: g# V2 @* s3 V* {, {- m1 y- |; F{; s* S' m! C H4 x- S1 w
int x;8 d9 A; w i0 Z5 l
int y;3 M# q' a% F% k# }. B6 l7 X
}grid;1 T; W; y# I& @$ t
! Y- e, y# @, p! ?$ i# N/ @6 F
//用一个类Knight实现算法。0 l, {6 k% n" I. R& u. t
1 z7 j) u, q3 l+ x0 ~# Z
& r3 Z+ }2 L# h: X' mclass Knight
6 g" U) T- ^: i3 L1 Q. ]) [{5 C7 T4 g" B* |7 e N
public:1 F9 O/ {4 m7 Z3 a" A
Knight(int m,int n);' t" M' Q8 j& s! G0 w7 F
~Knight(){};
: C2 D7 D4 j5 w% c* o. ` void out();
; O5 N0 m/ h: _* \private:( |0 j4 `2 C1 f# r1 Z, X
int m,n;$ r9 r) V! h9 ^* j
grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;
. `4 h7 k$ d6 [4 T int pos(int x,int y,int col); W: I/ z6 y5 y; d9 W
void step(int m,int n,int **a,grid *b);6 J* j) Y5 p& J
void build(int m,int n,int offx,int offy,int col,grid *b);2 i/ G8 K5 A0 `
void base(int mm,int nn,int offx,int offy);( h% h1 V4 c: V, l' `3 w% o) j1 |& ?
bool comp(int mm,int nn,int offx,int offy );" C: j* {" i! ~
};7 X) j" {) A+ J3 O) B, X7 J) o8 r
9 @) k' ?$ U m) i4 {. \
4 f6 x) S9 {5 Q0 p' x4 d6 r
U' }; @& Q) h) ~
+ ]8 q1 U5 e# H" r//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。
1 f; g6 Z/ w6 A//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回路。1 A7 N0 u: v2 Z5 x& U5 @* E& J a
* ~2 k# Q8 L2 Q7 S5 q- O3 A. |0 ]0 C) d* v5 N
//构造函数读入基础数据,初始化各数组。
" N/ U. p( s8 r' e7 n6 z0 d9 X- I2 q2 }: B. W' D, ?
Knight::Knight(int mm,int nn)
4 }( u7 h7 \! G4 f: K K/ x{' ~6 f3 L+ d3 r) p- O8 W" \' A2 f' t* E
int i,j,**a;
& I3 O" `" K- `/ j3 ^" ? ifstream fin0;+ k M/ V* `+ F! y, M
m=mm;n=nn;
) A1 B. f2 {+ @# Y b66=new grid[36];
+ a7 i( w; J! s: k b68=new grid[48];
, @& m) B5 e) F% r* j9 O4 z b86=new grid[48];
: X' `* s1 R4 y, C1 D9 `+ q b88=new grid[64];; F& [' w# t+ @
b810=new grid[80];. V, I$ p2 N3 M( D0 t$ i7 r$ U) b
b108=new grid[80];
8 y7 I: |8 E! ~4 \: {- b- p b1010=new grid[100];
7 K( b {$ d- G; n3 Y1 L b1012=new grid[120];& U) h3 O r( T4 N1 T
b1210=new grid[120];
* B& b d9 H3 c1 e1 e3 k Make2DArray(link,m,n);# m/ v5 K( s6 x1 s- V9 D, U; r; J' i, U
Make2DArray(a,10,12);
& }# X# c5 w! H' c3 k% H4 X
$ ^! _, r" t+ ~+ \/ p9 @/ _' I for(i=0;i<6;i++)
0 Z( m! O) }" X. ^% a6 k for(j=0;j<6;j++)
- Y+ j- K2 I t fin0>>a[i][j];7 i# ? h2 u4 P4 n5 W
step(6,6,a,b66);7 ]# t8 g2 r) `$ k5 u$ Y* n
for(i=0;i<6;i++)7 x1 I& b3 K6 }1 N
for(j=0;j<8;j++)
! l, [; Q8 x" o# p fin0>>a[i][j];
% l( C" P5 @6 A( q2 d step(6,8,a,b68);
0 K& J1 c* z& V; F _& P step(8,6,a,b86);. ]" e- V4 t" l
for(i=0;i<8;i++)4 P! ^# i; \( l8 ~! v) h d" {5 H
for(j=0;j<8;j++)
6 m4 A. K" s; G2 a fin0>>a[i][j];5 R0 _0 q+ N. q# J
step(8,8,a,b88);* F4 \( J. b! m9 o; `6 ?8 O
for(i=0;i<8;i++)
2 x# L$ t( J- K. j2 _6 K' a for(j=0;j<10;j++)
6 p7 {& d# E; o( I9 _9 c fin0>>a[i][j];
/ w' T1 u' i9 q" S5 {2 y step(8,10,a,b810);
) V/ C* d: y: h, C) t step(10,8,a,b108);" e7 G0 R$ g4 Y! v. K$ I
for(i=0;i<10;i++)
0 ^) G1 D1 L7 W7 _# M# r for(j=0;j<10;j++) + r B( R0 i' _! t' e0 u1 Y
fin0>>a[i][j];
r( |! H( w, R% U8 n$ d; Y% o step(10,10,a,b1010);' A- g7 U% M5 n, {# \1 l: b
for(i=0;i<10;i++)+ m- f& c8 l, F) ?% @5 U
for(j=0;j<12;j++) ) o# ~3 [. L$ I
fin0>>a[i][j];
v" u, U9 z" Q+ I step(10,12,a,b1012);
4 S) ?. ]7 N# g7 q+ k' ? step(12,10,a,b1210);# o2 t& W# b* Q) s- U
( x3 N# D& l# i0 R8 y
}8 g4 ?, f9 D7 W$ z
0 |# l' U% g; w$ |0 |2 b
, I, d5 h5 L+ ?0 ]* ^4 ~
//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。
' c4 |2 ^; D7 r- C( K+ D
. E+ G% E" H, Tvoid Knight::step(int m,int n,int **a,grid *b)# @% A) t, Q6 E u
{5 l5 U% _" o. g9 y1 m/ \$ v
int i,j,k=m*n;
, E, i0 v6 U' J' S: b/ o* P if(m<n)
3 N$ a+ c+ f6 s {
1 Z1 w9 t7 }8 V P: E& ~ for(i=0;i<m;i++)
9 @4 z$ l; U" ^! d for(j=0;j<n;j++)5 l8 U- Z3 t" X
{ \$ [# e- I( C$ f& S g
int p=a[i][j]-1;
) w8 `) F5 H$ E b[p].x=i;b[p].y=j;8 q/ f% C2 B! f0 k; X
}
" s# j* ^# a3 r! ?) {9 m( D: M }
U; i+ Y0 F# G% ? else{4 `% v2 a$ r9 e: v; I
for(i=0;i<m;i++)6 M0 [! m! W5 F3 N, i+ Y, |5 z! A% P
for(j=0;j<n;j++){
$ D' b) q: p) I+ K. u, j1 g int p=a[j][i]-1;2 r! @1 ?6 A" m4 \. c
b[p].x=i;b[p].y=j;
* E/ }& W4 [; m9 W! ~7 |% q+ t$ o }0 {3 w* y5 e: H- c. A$ l6 |9 h/ x3 I
}
" `/ i; Z' J: ^( |& s}
4 \, F* z; {+ { W. Q
5 e! a( C; u+ }( b; a F3 n. v2 a* S4 f) n* u, \' w J
//分治法的主体由如下算法comp给出。
$ g5 O6 G* i3 }2 `) x6 ebool odd(int data); p+ e0 s* N+ c
{% }7 {3 a' e8 }. S4 `6 t& C7 Y
if (data%2 ==0)
/ {/ r4 Q9 E; V. m g {
! d K: |: l. @' i# Q return false;
4 ~1 k9 ` ?" y2 H5 w& f7 @2 f# [ }
3 A! C8 O* e% K7 b return true;
x3 P- K1 n3 c4 d+ b0 Z# H}
/ O% `% V# V8 T4 G+ S/ s: |% k' E5 l5 b
( I+ {8 x+ I: M' B# @bool Knight::comp(int mm,int nn,int offx,int offy)
5 M. U1 o& w% o0 {0 r4 K{
3 {+ a4 o/ l. g0 w: E int mm1,mm2,nn1,nn2;* u: o' o. r# P* _% P9 A0 d$ o
int x[8],y[8],p[8];4 ]. Y7 \6 j6 ~) N/ M
if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;) O ~$ [% V4 ?; I& Q/ C: t
if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解; ]4 M" ?+ ~) T$ ^) S/ ?2 X
mm1=mm/2;
2 Y r( ]7 J- d% `' X if(mm%4<0)mm1--;3 `5 B! S8 g4 j' D
mm2=mm-mm1;
`. Q' q7 i0 \7 ?" L1 F0 z nn1=nn/2;6 N' t6 k q7 p4 l0 r& V
if(nn%4>0)nn1--;; H" q/ g) ^& e) Y* K- Z+ Y
nn2=nn-nn1;
, d" m* K* c1 @' } //分割步* P3 H, N& k. G$ h
comp(mm1,nn1,offx,offy);
: k2 b# {' y4 e4 i comp(mm1,nn2,offx,offy+nn1);, I+ O2 e; Q; ^6 J
comp(mm2,nn1,offx+mm1,offy);& i6 P0 ^' S8 @& I, `7 Y4 c
comp(mm2,nn2,offx+mm1,offy+nn1);1 T+ v; r) n; R
//合并步
8 d. I! ] p; N6 U2 p x[0]=offx+mm1-1;y[0]=offy+nn1-3;8 V1 ~6 q0 Z8 u( ]
x[1]=x[0]-1;y[1]=y[0]+2;/ o8 v2 y2 S) P" q4 Y4 N4 l' Y& c
x[2]=x[1]-1;y[2]=y[1]+2;
! F9 J. i8 e5 b) j( i( o x[3]=x[2]+2;y[3]=y[2]-1;
( y6 L( V6 d9 z ~2 e: l x[4]=x[3]+1;y[4]=y[3]+2;+ W- N; j! t. \! F8 G8 G
x[5]=x[4]+1;y[5]=y[4]-2;
' y6 V' Y( }% q/ Q6 v x[6]=x[5]+1;y[6]=y[5]-2;
1 F3 a) G- x* l; w5 X) H x[7]=x[6]-2;y[7]=y[6]+1;" z N$ O" n8 j) m4 E
. R* n9 r9 {) H5 S for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);
( R: q0 q0 e) W' Y$ w for(i=1;i<8;i+=2){
6 R) x, `# H% M& r9 W1 u+ N0 r int j1=(i+1)%8,j2=(i+2)%8;
5 b/ a/ @2 a! m* i( j4 A3 R7 H7 n* r" | if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];
8 O8 [/ g8 J# j8 m0 Z) X else link[x[i]][y[i]].y=p[j1];
4 p2 q* {) N3 r4 d if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];
! f1 O) U1 G! J5 y else link[x[j1]][y[j1]].y=p[i];5 h; l* h, M2 E3 D; |, y
}& [) P2 Y0 y& H& \/ H, A
return 0;
: Y( {# G2 \, H}/ R5 Q- K% C! `
% x; y- Y& T: |$ ~
& J' U+ D$ Z; a0 Z6 j: X% a3 j7 S//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。' c) J% n, D9 q, w7 t
/ Z2 u# n: G$ ?" m& q7 V9 pvoid Knight::base(int mm,int nn,int offx,int offy)
: m) _ X" f9 Z+ D{# Q! b$ ]/ p/ B: p' f/ R2 |
if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);
0 o+ Q. v, N# N: q4 z if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);
' L* }4 x3 h3 s+ c. ~ if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);5 q$ B) Y/ a9 g L- v
if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);
0 l$ a" w" v( ]+ U) R if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);& c7 m# X N ~ H* a U
if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);
, M+ h% f8 J# |2 v# Y if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);4 W1 V( S( B* `* z/ G
if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);7 Q7 t6 f8 d$ j
if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);
* [2 G: ~0 T% s: H2 L8 Q: H}1 _9 s6 `8 o6 q0 C6 a
9 @3 q, C+ z3 ?6 ^. B2 J( q% K9 @ s5 L4 W7 q3 y5 g
//其实质性的构造由算法build来完成。2 ], _) W* I3 F
2 d# T7 d* {: ]' C
void Knight::build(int m,int n,int offx,int offy,int col,grid *b)
) n+ L* w. f0 X# D$ a7 \{, ]$ ] C. r: H4 J2 j: c% W
int i,p,q,k=m*n;4 ?! I$ A, }! n( P$ b3 \; C" B
for(i=0;i<k;i++){
/ l, J: {0 ^2 `2 h int x1=offx+b[i].x,
8 F" X f6 Z# W9 V: j y1=offy+b[i].y, [7 I3 D, ], S8 ?# l2 @
x2=offx+b[(i+1)%k].x,2 D/ K* c0 O% ^- d7 ^/ ^
y2=offy+b[(i+1)%k].y;3 T6 E/ @4 G. {7 {
p=pos(x1,y1,col);q=pos(x2,y2,col);7 x" k# q, y) P7 c. d0 D
link[x1][y1].x=q;link[x2][y2].y=p;
: u( m$ V, A, \; D; O }
" w/ j' ]8 j0 g2 ^& [1 B}
' R c! h2 G/ h' w" d% X* s" v* g. g8 G, h, F* L
( W. s6 D+ t, ?- p4 m/ Q//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.
& }/ i% j' W* {, F! \
% W, I8 H [ b- d8 p% [% Oint Knight::pos(int x,int y,int col)- \% Z0 F- k9 m ^- d8 t* d" C% A
{9 }2 {( B; s0 E7 |5 ^+ c
return col*x|y;
( v; Z) h7 K0 R0 ~% t9 E}
' t4 x% V$ \7 Q7 v0 x0 P: L
8 ?* R H* f: f3 M* F. U U! Q
//最后,由out按照要求输出计算出的结构化Hamilton回路。- I$ r& ~# {* R9 ]: k$ |+ D
]5 i2 S5 ?! T$ N% a$ |: N! {' y
void Knight: ut()% `/ ^/ f$ ?% D) G
{
6 j' @6 l2 M9 O: ?1 d* t8 F int i,j,k,x,y,p,**a;
' }! {( `' C8 X# m- l& x. i Make2DArray(a,m,n);
. `9 E8 g3 s* [; V: o if(comp(m,n,0,0)) return;
, m% R2 [# B$ p- K/ X1 L for(i=0;i<m;i++). w! M9 v$ ?$ K H
for(j=0;j<n;j++) a[i][j]=0;8 u# P" A8 l8 I1 g$ h
i=0;j=0;k=2;a[0][0]=1;
; ~2 x7 \% N* z; H( _0 f8 o# i cout<<"(0,0)"<<"";
) G- `5 f' K( C7 M, h for(p=1;p<m*n;p++){
8 P2 g# K/ }3 x& c- V0 D7 b x=link[i][j].x;y=link[i][j].y;' P6 ], U- I% O. F5 b' `4 {( k7 _
i=x/n;j=k%n;- d2 W; I; {0 ^' i2 A$ v/ I
if(a[i][j]>0){i=y/n;j=y%n;}8 c0 k) _: H, U. R# p9 {
a[i][j]=k++;
5 n" m+ r. m# H1 c/ k; y2 {0 Y- V4 a cout<<"("<<i<<","<<j<<")";* `5 P4 d& y v0 ~, E
if((k-1)%n==0) cout<<endl;$ z# e1 Y% C( ?
}6 d' i, J: b* L! U% \. F, _
cout<<endl;
+ w/ S% S) e, D3 g for(i=0;i<m;i++){
3 P$ M* q R! O4 F- k9 S for(j=0;j<n;j++) cout<<a[i][j]<<"";, c1 N* B) ^% J" O) r! P
cout<<endl;) ?0 w# p" [8 w" C4 b5 b5 T6 H
}
' Z& d* N( D! \& O} |
|