- 在线时间
- 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, O( k$ B3 i( s( w
% e& g; U$ r# {; g$ m0 y
Hamilton周游路线问题
- w$ j; @ P: S; j8 t
4 k F6 @8 b: G9 q, v" v8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。& J3 F2 } h7 ]% g% |+ ]/ s
8 P" x* _! t/ b2 E' }" L
对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
* R$ M) H1 h( j2 M7 l: @5 A. a& r& d2 X8 I2 x2 I$ i
2 u/ y {3 o, t8 t% D$ g$ R
4 K$ W2 \; P+ W1 P. h! W3 {//算法实现:% _, d; m% `/ t5 n
; y A$ N. B' Q#include <iostream>
' s( J8 X! {6 O2 b3 o, I#include <fstream>
$ R$ U9 \: i% y$ s% {#include <stdlib.h>
9 ~# }6 H7 n2 s- E( k8 ?! }#include <afxtempl.h> " X8 v! d3 O W* a
using namespace std; J! o( ?' N0 _8 E0 M
template<class T>
) _/ B3 k) ?0 f" e# D2 j; d U& l) {% n; o9 E+ O
void Make2DArray(T** &x , int rows , int cols )
2 _: r/ t, z5 ^$ |, K{ 5 X( u* a' q5 g. t
//创建行指针
6 D7 S: A9 U2 _- G' J# `% c- ] x = new T*[rows] ;
5 _3 K8 e. }5 z# J //为每一行分配空间
, E0 w) d! D5 }! k3 y for( int i= 0 ; i<rows; i++ ) " U3 w. K n4 b+ h& Y8 @; d) l1 o4 }
{
& i. z( X( P1 |: w$ e- ?3 G+ O x[i] = new int[cols] ; 0 H9 K% W9 {: U. L9 W4 c: Q4 X
} . I9 \( J! L' Z+ q: G
}
9 G$ r# O r0 C4 Q; D, \9 ~template<class T> E) ~" h5 r3 ]- [8 `* J) H" D
8 b: @" W! T1 D# r# A1 c* a$ T/ [
void Delete2DArray(T** &x , int rows) / C; m |; i4 z1 u i8 X
{ # ]; ~; Q) ~$ ` S. N2 t
//释放为每一行所分配的空间 5 ?7 b/ U. a3 k7 A
for( int i = 0 ; i < rows ; i++ ) ' F/ U S9 {! B2 l
{
2 \' {( n. ~; b" w" b delete[] x[i] ;
! C4 p1 u6 b# ^, G$ @% b } 5 e, O f1 J/ u. }" R
// 释放行指针
F5 F5 Q- @7 _* i% v delete[] x ; # l. I. ?% E1 z+ ?. F
x = 0 ; 0 I6 ^! _" D* s) W8 V& m
}
5 c/ ~; t* o) s: d- A! z$ v0 U
. g( N: B$ |1 L1 Y2 f) Y3 N9 j//其中,grid是表示整数对的结构。' E: z1 K& \8 h' _9 x) Q
typedef struct
, Y8 V: V0 t' Q6 h* j( A) T{( S! E9 f+ }: B5 \
int x;
( G0 g- [* O2 H& `2 F2 [8 ~ int y;3 d! L) f' I+ f, D* p( S6 r
}grid;' P7 }3 I9 Z0 E) V# D
( z" `9 {4 _& u/ U! f//用一个类Knight实现算法。( u: H& g' }) Y& n, i
1 ?$ ^" S6 {( M$ h8 t. }
+ I% W* o" T# J! i8 u" v( mclass Knight
# V; r- z* f3 [) A{5 [+ ]" m$ v9 {( U3 y- ^) Z" _
public:0 ~ j# j" e$ W% U, t7 S
Knight(int m,int n);
# ~6 U# c1 E! m9 @( f/ x# f" D9 B ~Knight(){};
4 H2 G6 u( V4 t% P z: E* r' q7 ?) e void out();9 I0 [0 C* L3 ^" A
private:2 e- \8 p; B3 `/ A* H# h
int m,n;6 G5 H& E" A8 w% y0 l, Y
grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;
. h6 |) M4 }3 `( a) Z( D7 n int pos(int x,int y,int col);- n1 S* v. [4 N4 c
void step(int m,int n,int **a,grid *b);% H7 |+ Z2 i7 V; [6 r
void build(int m,int n,int offx,int offy,int col,grid *b);
& |& q: f9 \( ^ void base(int mm,int nn,int offx,int offy);
+ ]/ E8 w: S- M u bool comp(int mm,int nn,int offx,int offy );
/ X0 E, H2 u+ X# [, J9 b: Y& `' v};
" _3 t2 G" s9 j# _) _. H, V8 _* P6 ]
' C/ U2 }) i' e+ d# p6 z6 m
, X4 B& f4 D* I3 V; n
2 T/ v6 `" L u9 e//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。2 P7 I$ w7 L5 H2 F9 e U
//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回路。
2 u! u9 [6 {+ q
# C5 H6 C1 B- F7 h) M- L3 g8 r1 h3 M( V4 Y) J$ J- y
//构造函数读入基础数据,初始化各数组。
0 Q) e: }5 C) x2 M6 i
3 G+ l- Z( G. f- M3 X8 KKnight::Knight(int mm,int nn)
, q+ d# H: E, k- \+ ~( u7 }{
" v+ u: K# w# G! o7 X8 L. O. | int i,j,**a;9 h3 ]$ ?' F4 f/ U+ i2 I
ifstream fin0;( g c2 o5 h5 h- i
m=mm;n=nn;! ~, W: S2 C. b. L, e; b9 _0 k8 W
b66=new grid[36];5 K# z3 z$ I1 h4 s/ t/ C% Z
b68=new grid[48]; k. J* b- X) Q# A- r
b86=new grid[48];( E1 i5 j* ?( O# ^5 J6 t
b88=new grid[64];
( J7 m+ J' N9 ]7 M, q5 w b810=new grid[80];
* E2 F: a3 k) }$ ]9 G/ Z b108=new grid[80];
# L, A Y* U; H- h9 J b1010=new grid[100];6 h# o5 X3 @& n9 n2 Y! z! v
b1012=new grid[120];
9 t! j* M* d4 L! l$ {9 |% i b1210=new grid[120];
* Z+ ]' [; |5 [7 ^1 C Make2DArray(link,m,n);
4 a4 n$ D3 a6 @. G5 o% W Make2DArray(a,10,12);8 }: c* d! O# c4 K4 E/ W- O3 u0 A! v
- O7 `6 U. s8 y6 J1 { for(i=0;i<6;i++)7 v4 v6 m/ |6 a5 Z6 m" ?" b' ]
for(j=0;j<6;j++) " F6 V: R9 Y* W6 N( m) b: T. @. O
fin0>>a[i][j];1 v1 s' z) C4 Y E3 N; d% f8 A
step(6,6,a,b66);
, r5 x3 o6 s1 a- Z ^ y4 V1 j for(i=0;i<6;i++)- t2 P% r) f- a( L6 i# ~9 W O5 O) Y1 ?
for(j=0;j<8;j++)
j1 ^. j: `6 i) K+ y" f fin0>>a[i][j];$ S2 ?# E2 y! W+ v% S& V
step(6,8,a,b68);! g. O8 a( m' W4 }4 c
step(8,6,a,b86);+ H. l- K& M( H1 T! n
for(i=0;i<8;i++)5 i0 K( {0 H$ i* F" J& ^
for(j=0;j<8;j++)
$ B/ ^0 w c0 j! e& v3 d fin0>>a[i][j];
3 t4 q& X0 I: g! W' o& h* o# b) z step(8,8,a,b88);) n! i; m% a* [' R, m$ `
for(i=0;i<8;i++)
" i' U; V" U+ q6 k) D9 d, W1 W) k9 y for(j=0;j<10;j++) 6 f" E- Y; z3 |
fin0>>a[i][j];
# v" I W' |) N3 }2 P5 R1 n step(8,10,a,b810);
! l" d7 p! @2 W/ f( W step(10,8,a,b108);
7 R! b7 n& @; H, A for(i=0;i<10;i++)
, w# L0 M+ H+ i: o4 l4 ]$ D/ n for(j=0;j<10;j++) ( v. K/ Z! p' w' @; Q& R
fin0>>a[i][j];. S) i2 W3 r$ b2 k' f; T
step(10,10,a,b1010);0 t. k' e" n$ d2 _ y
for(i=0;i<10;i++)
0 R8 G' ?/ u! j& x3 Q. c: Z4 a- r& ? for(j=0;j<12;j++)
; x* o; Q( h6 M) x! @ X* v+ O fin0>>a[i][j];$ G. a" i; N, P' K2 p0 J9 B
step(10,12,a,b1012);) m6 n8 K4 K% q* t: I6 X, G
step(12,10,a,b1210);5 W/ L1 Q- D$ o8 F3 B6 Q4 p
' p/ u, T. W- `4 n7 s+ u( r}
% V/ g/ r9 l" n
3 Y& @6 K4 I! A+ t
?+ V$ w; x1 }9 p2 B$ W% S9 z//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。; p" u8 S' k' ~
3 v9 k" l* D& }void Knight::step(int m,int n,int **a,grid *b)
3 `. [/ f/ V, }# r4 L{5 J" D2 p/ I2 C: a& N& S
int i,j,k=m*n;
% A% [& e/ y9 S0 P+ s3 v if(m<n)
! ?4 n. ^( D& s0 z k. c6 `5 M {
: ?/ L; J6 ~# O+ W for(i=0;i<m;i++)3 m+ O9 R1 P, ~# W
for(j=0;j<n;j++)
/ m0 |* R; A; M0 Q, v {5 ^/ l# k# i# `7 g
int p=a[i][j]-1;
& |5 a/ g0 ]0 U r1 w- W b[p].x=i;b[p].y=j;
! G7 n. V0 \7 e# f( m- I }
( c2 J5 ^3 ]7 k& T3 {3 b P }& K% T E& l5 u
else{8 c& |8 F/ c3 a, n
for(i=0;i<m;i++)0 O' P# U6 p% ]
for(j=0;j<n;j++){) L& e' x/ d5 W/ T# v- Q1 |$ i
int p=a[j][i]-1;0 j7 v. y7 `$ \2 U6 s W& ^. A
b[p].x=i;b[p].y=j;
; ^ k- s1 M# } }4 N2 ~: I3 P! i' i5 \/ c
}9 z% u2 ]+ w- r! o, e. a! ?( D
}
. R( x+ u, I% {% W' ? U2 u" e0 m5 o5 [) F
6 Z: z+ o: y8 r2 @% D//分治法的主体由如下算法comp给出。
" Z5 z9 A" W& C- u2 T, `2 F( [bool odd(int data)7 Y( \1 N4 K8 o. P8 k; Q% I8 `& b
{
7 c1 s: t1 {# r2 D# ^! c if (data%2 ==0)/ f' ]0 ^3 @0 _. P7 y( G
{9 _0 x8 L) G0 {5 q0 i1 }
return false;5 D2 U$ X" L) ~- ]& `
}4 ~9 q7 m d; T& u
return true;* U& q; e0 h4 l$ a! ?# {0 T) ]
}
5 s1 K8 K& b7 P, m0 }# X. ^2 n7 B7 B0 I
4 p" y+ x4 r6 A. [$ \9 N
bool Knight::comp(int mm,int nn,int offx,int offy)
6 f# `7 S' x5 w; y* c{
. g( k- L9 J* q2 ]8 O int mm1,mm2,nn1,nn2;6 A% X% A8 U% c1 T; w
int x[8],y[8],p[8];
. O7 E, v4 ^% J; l6 N if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;1 J! c+ v. @( b: x3 e5 x$ m' ?( ~
if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解
% U/ X5 o" C+ k5 Z1 d% \7 J mm1=mm/2;5 e$ k% {# q3 _9 Q( v$ A! q2 Y0 E# [& {
if(mm%4<0)mm1--;
6 {- g* s" V4 E) h2 R0 G mm2=mm-mm1;+ H; W! `& B4 z$ r! g' R3 J
nn1=nn/2;8 }$ ^: k A( { {
if(nn%4>0)nn1--;2 {0 ~5 t2 J: S' g* K: a
nn2=nn-nn1;8 x8 C4 D' L7 B; m2 i3 n# l; M/ u
//分割步
3 h1 d9 X- {- {/ p$ Y$ C7 { comp(mm1,nn1,offx,offy);
1 Q3 N7 `9 X% d; p* j comp(mm1,nn2,offx,offy+nn1);% `& q; E: J" } N1 g. l
comp(mm2,nn1,offx+mm1,offy);- h7 F3 R; N- I1 L2 p
comp(mm2,nn2,offx+mm1,offy+nn1);1 W" y8 |4 }* n6 z) J
//合并步. L- ]" \& x: ~; U/ C
x[0]=offx+mm1-1;y[0]=offy+nn1-3;
* w6 }. x9 u9 p' m E x[1]=x[0]-1;y[1]=y[0]+2;8 m: ^, k$ R$ X' @' W
x[2]=x[1]-1;y[2]=y[1]+2;% d* @: C: b$ D1 F0 Z: G. N9 [, |' b: q
x[3]=x[2]+2;y[3]=y[2]-1;+ x7 H1 ?+ o: ^% c
x[4]=x[3]+1;y[4]=y[3]+2;
) b/ ~. I. M+ }8 p$ K3 T4 s1 v+ \& L( m; ` x[5]=x[4]+1;y[5]=y[4]-2;( A6 ]5 N3 ~$ j& R4 P
x[6]=x[5]+1;y[6]=y[5]-2;. ~0 c5 l/ i7 i$ G2 ~- Y6 h
x[7]=x[6]-2;y[7]=y[6]+1;
- k* \5 j8 P8 e
$ @/ j# H' ` J. r0 r for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);# ^! [6 a$ i: I+ p' \$ X6 J
for(i=1;i<8;i+=2){0 [: J( V( L5 w- d4 U0 f. f
int j1=(i+1)%8,j2=(i+2)%8;
) c5 U7 q. W7 r/ ~8 M9 z8 A8 N* } if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];4 _+ H U) G- Y7 m9 Z Q0 a
else link[x[i]][y[i]].y=p[j1];
e$ E, S& K4 u+ f9 P- z if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];
, a/ q! ?5 w! F4 \# t else link[x[j1]][y[j1]].y=p[i];
( f5 O; z9 M( L9 c( M5 m! l3 S9 T+ W }0 C8 n# j$ B4 ?; t
return 0;& c8 f: Q8 n; o& m# h
}/ J! x5 _0 M b3 I
" l- t; K& q8 z! K3 u6 l( l+ W0 r$ k! E$ a$ x
//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。
+ a/ M2 M. [$ A/ z! p( t2 L: f7 O, p' `. B+ q( K" ~( G
void Knight::base(int mm,int nn,int offx,int offy)
9 b2 j& l# V. ~1 J3 R# p! S{
! `" `, Q+ u* F# k if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);
6 m1 P5 [. f9 P if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);7 H" i7 g$ T3 I* p9 H4 x
if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);
! g, e3 r# a. D. X) o% E if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);% Y/ D7 t7 }) j' ~2 E/ v
if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);
V2 s- ]" c D" k) R, I, z if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);
7 F$ @! O m- A( f if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);
! y& D" R5 L/ X* c9 m5 ]6 U" h if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);5 E3 Y( z# V4 y* B$ w
if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);
& F. i ^) p; R, V& N}9 v4 t8 U8 V, T3 A" _5 Q. {
O% s S. \1 v
3 |, I8 v( A6 m8 e% n4 U//其实质性的构造由算法build来完成。
+ U; F5 h1 \3 m+ a
5 T+ ], K# x5 Z1 h3 ?! B( E) {2 L1 tvoid Knight::build(int m,int n,int offx,int offy,int col,grid *b)9 G- H$ t7 k3 t
{- H4 n6 _8 }8 W5 |) d4 i( r$ z
int i,p,q,k=m*n;* K+ H9 }8 ^* Z
for(i=0;i<k;i++){
. G! G& S, u! r* O. v int x1=offx+b[i].x,& {; Y/ n/ d8 Q K; _' S
y1=offy+b[i].y,
! I4 P Z2 W8 v7 S7 L0 x+ x x2=offx+b[(i+1)%k].x,( Z1 B5 U" a$ I2 p
y2=offy+b[(i+1)%k].y;
6 P' |: M' N1 g: Z3 `$ ] p=pos(x1,y1,col);q=pos(x2,y2,col);
g0 }/ i# I. l2 T# [6 F link[x1][y1].x=q;link[x2][y2].y=p;8 V7 }2 S* u+ P
} 7 ^) |, k2 @7 b' e! \+ H
}9 D) J9 c6 q( k+ r( M0 x, P
1 G+ ^# P& V9 l8 p8 o
# x- {3 W) f7 J: t% A# P E* ~//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.& K# L8 v, C8 F& v; i) L
# z: U V; [! s, kint Knight::pos(int x,int y,int col)
0 \& }+ H9 s- r* W8 H6 Q{
+ D5 _1 q; w( d* f1 E5 P' d return col*x|y;8 C: |7 f; [0 z# D- C9 I- x' s4 j
}, W6 I) f9 N: D$ B( H5 T
, V A' ^4 K0 J, Z/ [" @
. X$ @8 f$ G) U' T* `//最后,由out按照要求输出计算出的结构化Hamilton回路。6 Z8 h4 @4 B: _
$ d8 Z4 C; u) w* D
void Knight: ut()( j& H/ c% m: t+ u4 d# T' n
{% p' z; b( n8 [
int i,j,k,x,y,p,**a;8 \: m8 [: w9 _$ y6 _
Make2DArray(a,m,n); }! `4 m y' o6 m* ]9 Y6 G1 n4 t
if(comp(m,n,0,0)) return;
3 ~+ c: l9 G; Z: ~8 Z: L7 ] for(i=0;i<m;i++)
2 s$ {" G0 s R1 N h for(j=0;j<n;j++) a[i][j]=0;# w" C. p+ `! K5 G, f! n) L7 f5 D
i=0;j=0;k=2;a[0][0]=1;' Q4 ~+ c& }5 ~. Q
cout<<"(0,0)"<<"";
- O- p$ W3 ~" } for(p=1;p<m*n;p++){5 w6 l# J5 G: Q. y
x=link[i][j].x;y=link[i][j].y;, a: l8 r1 o3 M3 n' W u
i=x/n;j=k%n;: M9 ~ X* [$ A* I; H
if(a[i][j]>0){i=y/n;j=y%n;}
4 e) G7 @# S G: u: f9 K6 W a[i][j]=k++;+ d3 j) t2 A7 Z7 I! d1 T( _+ V
cout<<"("<<i<<","<<j<<")";' J6 \( ]7 f/ o" G) U
if((k-1)%n==0) cout<<endl;- `, a: P7 U) z* ^! p6 t
}0 _( ?6 B; f# I/ A2 b
cout<<endl;
5 P) i7 _+ A( W3 u. }/ ~& S. H3 Q for(i=0;i<m;i++){& h# a8 ~+ K: m9 O; \0 b
for(j=0;j<n;j++) cout<<a[i][j]<<"";
8 F0 E7 R: h$ Q! q4 S: E" B. M T7 j cout<<endl;
; m, d0 M: _6 q% y1 l. i }6 D. p- z2 E: P9 V4 O2 B, L
} |
|