- 在线时间
- 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
: C6 C7 M) J9 \5 z/ Y" L1 P1 S0 o) c/ b2 l4 E
Hamilton周游路线问题
/ o, ?# ?5 F! g, a+ i5 F( O. A+ d& {& k; P! Z' B* R' v& V& k
8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。
' o/ s8 H; M) @- ~8 c. Q( Q. U8 n- S! e0 k- R: x7 }
对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。& _" m% F! w8 H
( ?8 h3 x% `3 x+ H* D
( P& f/ x. E. L' M+ f' s
! _% ~+ U9 Y3 m0 m! b0 p7 p//算法实现:
: p5 `( X' M# R+ K6 X7 D
, u3 |% @% Z" l& O3 p: S& h#include <iostream>
3 }+ A6 q5 W# a# u+ Y3 y2 D#include <fstream>
3 q) w+ a+ a9 ~#include <stdlib.h>
; O5 S5 t) L8 K; s9 b( @8 V2 V/ c#include <afxtempl.h> 8 _$ Z/ p; D. }2 B
using namespace std;, D# n) v7 @9 W$ ~+ R# { k
template<class T>' e" H: p3 m1 P$ p+ \
2 w4 v/ Z7 }* r" C7 a
void Make2DArray(T** &x , int rows , int cols ) $ S: m- y2 }3 b1 q
{ p, l/ m6 l' E% z ]; E* a
//创建行指针 8 k) X" j4 d: _9 U2 t( u3 l3 c
x = new T*[rows] ; % s: |9 |; s; ]+ H! @& u' w1 _
//为每一行分配空间 ( D; Y2 ?+ ]0 o/ G `8 R
for( int i= 0 ; i<rows; i++ ) 8 l, T1 [0 Q( a; C
{ % \- K9 ]5 k/ s* u R0 n7 R
x[i] = new int[cols] ; 2 q' T5 P" K8 B# x0 I5 V' z% e
}
4 O$ C+ L! m$ H# H- k}
- [' J& |5 g1 M }- A' Htemplate<class T>/ e9 m0 y8 L: n/ p( z
+ `) p0 d4 B7 b7 a9 svoid Delete2DArray(T** &x , int rows) ( C2 w# q2 H# h4 S
{ . o7 I f5 p- G/ `' @3 ^
//释放为每一行所分配的空间 * S" x7 h7 Z# j, }4 h$ `1 B$ y3 V
for( int i = 0 ; i < rows ; i++ ) ( E6 D' W. q6 G& s' B
{
+ M* i% s' |3 W4 I delete[] x[i] ; / k+ ~1 m- O* D- F
} + n+ O5 S( _9 Y2 A) \$ F
// 释放行指针 0 s2 }* }' a' G
delete[] x ;
: B9 N$ g3 R% g x = 0 ;
# ?" l6 ~8 k: j1 z* j+ N}2 B e# e, W3 J: @9 _
# Z! ?2 \- Y4 a: S1 g7 w//其中,grid是表示整数对的结构。
: c+ e7 l5 k4 J) ?, z5 btypedef struct
8 D; ?' f* @5 s8 v6 T9 h" E5 W+ e{
' h) y& H4 D" |* X+ P int x;) T# W: N1 Z" \, G6 d
int y;
9 \4 @/ ~+ \2 f4 K' v7 h* E}grid;
" u* S) G8 {6 L' F2 T7 U8 w/ Z* |! m) C6 v: I
//用一个类Knight实现算法。& ]) E( O; }1 t! i- B% z- e
6 w' T: x. q! w$ F0 X3 ^
9 P8 b8 H1 s& F6 S+ x3 Y* P0 i* T* C
class Knight4 L4 h( Q0 n1 t" r+ `1 ~# E
{
$ c' a7 W3 E7 _2 `& E1 c ypublic:
% o$ O) k- R, e# y Knight(int m,int n);5 O0 O3 g; ^( r; Q
~Knight(){};2 \! M; Q5 @3 o9 d/ `8 A- [
void out();
+ [& g8 w# J$ }private:
7 o/ @+ l% ^& T M7 Y7 x int m,n;
) Y* A2 _( y5 Y4 V0 e( K9 b grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;
0 q+ Z2 J: A+ q int pos(int x,int y,int col);
5 u0 W6 q# U! ?3 x/ l5 `1 `) V void step(int m,int n,int **a,grid *b);0 U0 m: F/ o' S# R5 Q2 r
void build(int m,int n,int offx,int offy,int col,grid *b);
Y6 X! d+ N6 l2 L3 D; @* B/ V void base(int mm,int nn,int offx,int offy);! W% c4 }" _- {4 g; U: P
bool comp(int mm,int nn,int offx,int offy ); l3 G3 r5 b: o6 O7 Q
};
2 o) L- S5 p- N0 }6 b3 Z9 z' R% ]6 o1 r6 o9 }" m7 R
) e: o/ A* f8 N4 p0 p( s
7 C1 O) Z6 G; b" R- C7 x
2 \' Y) _& L0 Z; ~. A//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。3 c' m8 v) F: t6 b; k6 y/ J
//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回路。! w' l, E5 J: N
) B5 U0 m4 m& Y& d; v" p) z
, j' a5 t, _5 C) K! z/ n//构造函数读入基础数据,初始化各数组。0 q8 h/ e* H5 |4 T$ L! ?- q5 c
! Z7 I" K" B9 b: r7 L- }Knight::Knight(int mm,int nn)& Z% B8 P O# Y d+ E A- G
{
9 M* N- m% J) x" p. o4 I' E A int i,j,**a;
j2 O3 A8 K. s7 f3 r; p ifstream fin0;
( ?6 E4 @7 `6 Q5 [( P. b m=mm;n=nn;
" M( _& a0 I6 H b66=new grid[36];" \9 U! D' U8 }9 u
b68=new grid[48];( U9 b* v n4 c5 l, Q7 L* v- W* v$ Z
b86=new grid[48];* }+ n& T3 H- J+ z- ?0 p# q b% H
b88=new grid[64];
% Y" w7 v, O3 L+ [' W b810=new grid[80];0 y9 q$ X* ]5 H3 V7 |1 I9 y: A
b108=new grid[80];
0 ^8 b7 e8 Y* _' a b1010=new grid[100];( \, M- Z' M" a* K% b( J2 k
b1012=new grid[120];
! E4 ^' a( J: Q- t9 g8 l* ~3 y) S% N b1210=new grid[120];5 }- G6 c- l. i' J1 t
Make2DArray(link,m,n);
( M6 T1 X) M4 ] Make2DArray(a,10,12);( r) p$ j( ]) `2 m6 D; S( n% \
+ _: w: |8 r! m& M" K; T/ o5 j b
for(i=0;i<6;i++)
/ E K8 B9 G1 z( g; e' T6 N' b% b3 O for(j=0;j<6;j++)
$ Y. u& D7 Z1 o. e9 A fin0>>a[i][j];
& ?; I9 v4 q7 |5 s step(6,6,a,b66);
. {3 D& r4 w/ m* w% z for(i=0;i<6;i++)! a; e+ w& ~ P
for(j=0;j<8;j++) : ]# S) p U4 Q* Z4 q5 g' ?2 s. d* X% W
fin0>>a[i][j];
+ x/ i. W0 m5 o: G3 u) T step(6,8,a,b68);
7 U' {8 X0 O/ @9 N; {6 Q, g* T step(8,6,a,b86);; ~+ s8 U! Z8 g# h
for(i=0;i<8;i++), P0 R6 x+ ?; N6 U2 {% Q7 }; Q
for(j=0;j<8;j++)
. }5 M( C" |. Y$ c/ { fin0>>a[i][j];
8 }& j& y, C' H% @: @, v9 I! h step(8,8,a,b88);: Z4 ^! n! Y" A7 o2 R9 {! Q
for(i=0;i<8;i++)
. e a; |* N) X2 X) l# a for(j=0;j<10;j++) 8 S; W6 G. ^4 j6 r, f; r2 f
fin0>>a[i][j];
, n7 P$ f7 f5 C3 T6 e9 k/ J0 ~) Q; j step(8,10,a,b810);* N* d+ r/ ^0 M
step(10,8,a,b108);' f0 O7 | r* l* u( e6 T$ D9 s
for(i=0;i<10;i++)
( O- A& `. O' A3 H z for(j=0;j<10;j++) 6 j; R+ m. h8 O- y5 s, U
fin0>>a[i][j];& k+ ]1 U' H* ?# d) \1 x) ~
step(10,10,a,b1010);9 K$ ]% N) T- b3 l& M/ H7 U
for(i=0;i<10;i++)8 [1 n. g2 e3 I+ N* N5 c2 O
for(j=0;j<12;j++)
# J4 U7 A& d D' b& |: a0 c; f fin0>>a[i][j];8 _: x S z0 ]+ G
step(10,12,a,b1012);
. n4 d) [# t9 `; T. X step(12,10,a,b1210);
5 n- s) Z" x& t' `& z2 @ 2 X7 I( G# l+ m. m4 t5 V" U/ R
}! S0 J% W, ~5 @/ n9 ~& [$ o! {
4 H+ s1 `. [- }3 l! u# [7 H& Z' X. {* P% |3 o
//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。
; ~) Q8 Q% |, i8 u0 ~$ y& h' y% w" [# n6 d' k3 g$ d g
void Knight::step(int m,int n,int **a,grid *b)
( E5 @9 A% E% b- @7 w. B0 B{
3 l% Y( A- G9 _4 a. C' L int i,j,k=m*n;! M# u7 g. g5 _+ S+ [
if(m<n)
' v* a8 n3 @( y4 w6 } {
7 x) {9 M. q$ J: m( x H3 g for(i=0;i<m;i++)' e* A4 q: k9 q
for(j=0;j<n;j++)9 P5 `: k( B7 Y4 Q% q8 v
{& x3 S- m3 u: x! @
int p=a[i][j]-1;/ f6 q* S3 F; ~. W: W1 F3 h( V8 x* [
b[p].x=i;b[p].y=j;: ~: I) N# f$ n- \
}$ C, }: d$ H2 Q# u$ E; k9 b
}
9 `7 f: z' r+ C2 Y else{2 b, @" h& T5 r- ?, h9 z
for(i=0;i<m;i++): h" f+ O% X7 _* n
for(j=0;j<n;j++){' d! Z7 u0 x* Y0 `. T! b
int p=a[j][i]-1;6 O' Z4 f9 r# n2 U
b[p].x=i;b[p].y=j;
! v" {% P9 R; n: B# E }
! z' b. |" E* x }
0 B+ t. U# b( [& m+ L}
: A9 I. ` T: U4 w C$ m4 B3 D2 s6 R1 @: F! D, I/ w+ B R# k7 r2 E6 M
. D8 F6 }. | K% P//分治法的主体由如下算法comp给出。
! }* z7 d( j: B) P: a8 G5 mbool odd(int data)
, t! c+ n# q; J& R9 o" ?( A" w{8 J o N3 `& [* ~0 _: {0 @' ^1 `4 c
if (data%2 ==0)
$ [1 w+ t, H& G {! U3 K h9 j5 O, O- Q
return false;
$ G! e7 B3 J$ o9 ]% \ }
4 { J3 G% }& N& D return true; h; U: S+ }+ W; r" [
}
% U ~5 G+ k! a$ R# ~2 Z
+ B7 I/ A2 ^- S p7 v) K0 l' t% M; @$ C
bool Knight::comp(int mm,int nn,int offx,int offy)' x7 M; C6 l) G/ j# Q
{% ]+ f9 ^' f" f" b
int mm1,mm2,nn1,nn2;6 C* D/ V9 a+ Y% j0 ^+ I4 C
int x[8],y[8],p[8];$ Y0 K% f5 U9 a7 \
if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;* _3 m& O+ o) {1 P) `! ~2 {
if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解6 e3 k4 M5 `9 g6 }6 u
mm1=mm/2; {7 r9 P$ a6 J1 V e+ H
if(mm%4<0)mm1--;
* ~8 \; V* |3 A2 O$ Y, v mm2=mm-mm1;/ }* F' g* A5 p8 }' q
nn1=nn/2;
) |. q6 ]+ K0 N$ @" G, v' p) E if(nn%4>0)nn1--;
4 y4 M- r9 w9 [' u8 \ nn2=nn-nn1;3 `5 b1 e$ s: v& v5 a
//分割步
7 k: @* K; `! C* d, n0 ^ comp(mm1,nn1,offx,offy);
5 @+ |0 z2 @% Q5 Z& R8 [ comp(mm1,nn2,offx,offy+nn1);
T* V; s7 T1 l" N! g. B comp(mm2,nn1,offx+mm1,offy);
, i, Y% z, C f comp(mm2,nn2,offx+mm1,offy+nn1);' ]8 `* D9 w9 N' l- \- K
//合并步
% C: G- G6 M7 E3 b+ w5 n x[0]=offx+mm1-1;y[0]=offy+nn1-3;
$ U: S# T6 a: Q+ Y x[1]=x[0]-1;y[1]=y[0]+2;
1 T j) Q( G- v/ H/ L, i x[2]=x[1]-1;y[2]=y[1]+2;
5 C5 R1 E J' W) k% \ x[3]=x[2]+2;y[3]=y[2]-1;
: b+ W# t5 j L A x[4]=x[3]+1;y[4]=y[3]+2;
5 v7 `; d4 O9 C6 x* G x[5]=x[4]+1;y[5]=y[4]-2;
5 D5 H% P& {1 v( r% t( { x[6]=x[5]+1;y[6]=y[5]-2;, K. t/ p! _" W$ I' b: k* U
x[7]=x[6]-2;y[7]=y[6]+1;
" D3 H/ h- h7 k$ l" q
1 F( k/ z% O) D8 T* ~, P# y% Z for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);
" |1 P" B( z6 w- K for(i=1;i<8;i+=2){6 i3 _! K) s d. j
int j1=(i+1)%8,j2=(i+2)%8;8 Z8 V1 N6 i1 S" J j: b8 u5 [& a
if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];
- V! ?2 v+ N5 S8 S [ else link[x[i]][y[i]].y=p[j1];/ ~3 o6 j- q' N9 @
if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];0 T( ?( S4 T6 ?, ^; F
else link[x[j1]][y[j1]].y=p[i];6 R" z6 E* f h4 \2 m, U+ J0 v' T- s( F; u
}
[6 O# N% ]! A. `- D/ A0 @ return 0;
: [( m, g9 L. ?2 S2 g6 r1 @4 R$ U}
, L2 Q- ~( s( S4 s2 B& r0 W
e) t0 u9 }" z/ w3 Z$ O8 F' Q/ n
1 W4 @. n* H3 [' U0 S//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。
! i3 q" n0 _8 l; ?6 B5 ]2 b+ R1 ]) P) p# u* {3 h7 r5 o$ F
void Knight::base(int mm,int nn,int offx,int offy)
5 W v8 |& b; K' U+ Q/ x3 x! [! B. K{
: Y" i& }* ~3 m ~- V if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);
! Y5 q* o3 j/ w1 e) \/ W if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);
* H, t1 T: h7 t! _ if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);
$ E- |* @+ W; l6 J# u$ m if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);
+ [; C- U3 P9 [0 Y8 ^+ Y6 c9 F& N if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);8 H6 h9 c. }; R1 b/ h' P
if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);. S! y$ \5 E4 U3 e. \' q1 ]& ~
if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);
+ w9 n/ d3 |$ v) H if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);5 u- w# L t5 P& n1 t
if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);
5 n/ P( W" t# {0 w& X/ s7 o}
2 s2 i3 H, Z5 P6 B; Y) F
) y: s* _; V: y/ X- t" r/ d; E$ c+ B: y( h* T8 [
//其实质性的构造由算法build来完成。& Y! _1 o) i7 Q& s0 B6 g
7 u( d; z; q/ \5 z* d% p
void Knight::build(int m,int n,int offx,int offy,int col,grid *b)4 I! x+ q: Y1 m; }9 m& i
{* r) `( ]( ]8 P% u# Q) d- T* I
int i,p,q,k=m*n;! h1 }# @/ [: S# C! f0 I. u/ w/ x
for(i=0;i<k;i++){2 K6 x l5 d2 E$ l' |- f
int x1=offx+b[i].x,9 t/ V" J1 r5 U7 m: e ^% a i
y1=offy+b[i].y," D# ]$ o1 n6 w) _& C0 h' O
x2=offx+b[(i+1)%k].x,
9 U) l) I/ m3 E4 M- U9 [3 T& c y2=offy+b[(i+1)%k].y;
) n1 Q0 t* ^7 E1 l$ ^9 P* H- X p=pos(x1,y1,col);q=pos(x2,y2,col);3 ^! _1 D( N+ R& z" e
link[x1][y1].x=q;link[x2][y2].y=p;
% Q% J4 I- C3 O5 A- N6 Z: O* d } 6 I: Q* W2 x) U) z
}
5 j+ Z( \ q) \$ x" s6 b9 I2 `* r) S# N- z; J: u
0 r3 U, G4 s3 C9 Y8 W- W' w* R
//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.
+ e. z9 c! W# Y2 y+ c
3 U- ^) g- ?. i3 Z7 Pint Knight::pos(int x,int y,int col)
: x) I5 s- Q) t$ ~, `# I l. e5 a{
6 R9 k9 }6 f3 u return col*x|y;& f4 t# V1 \9 G3 Y$ s1 d$ O# A, g
}9 b# g8 U5 Q' ^4 \4 E3 Q
, O, [" _3 x9 F; h0 m
0 [ L. ]. z$ i' L! p% o, g//最后,由out按照要求输出计算出的结构化Hamilton回路。$ ]* \+ {" o: ^" B% m/ b5 ?
/ ]6 f) b6 F( q9 S. lvoid Knight: ut(); A5 h3 O8 d, s0 X+ X
{
% D. ~2 Z$ P) i6 c+ S int i,j,k,x,y,p,**a;/ N! m1 z" _. K- s5 V1 R4 ?
Make2DArray(a,m,n);6 E* f! y9 o4 ~& `$ ~
if(comp(m,n,0,0)) return;
+ w- ~, x' Y; k d+ }% A* G+ w$ v for(i=0;i<m;i++)
0 E+ X" ?( }$ G0 V. p W for(j=0;j<n;j++) a[i][j]=0;
, E* W) R' K% ?- M; u4 r i=0;j=0;k=2;a[0][0]=1;0 m! P$ F" b$ }9 I6 Q' Q% s
cout<<"(0,0)"<<"";6 Z1 ^8 G2 s7 A9 j( g
for(p=1;p<m*n;p++){5 ], O* R8 ]. J
x=link[i][j].x;y=link[i][j].y;1 z# ?) {3 u7 f: m
i=x/n;j=k%n;) H* @ K* S7 ^& a c$ F
if(a[i][j]>0){i=y/n;j=y%n;}6 [6 ~* t3 B, A X, b2 q% }' A
a[i][j]=k++;( q* ~/ Y, Z6 o+ _
cout<<"("<<i<<","<<j<<")";$ O8 j. o9 m2 A/ \
if((k-1)%n==0) cout<<endl;
4 a5 r2 d6 E5 E" X2 K0 f }4 N" X. Z7 H1 X, x4 E H' ~" [* P
cout<<endl;
3 P# q0 `* D# Q6 n6 ? for(i=0;i<m;i++){! O. N/ H9 v" I2 J
for(j=0;j<n;j++) cout<<a[i][j]<<"";
' b8 h2 C9 s6 W* ?* U; e cout<<endl;
8 N, K( W* q1 y5 G6 r }# F- q, l* B6 V, F$ z0 f( d
} |
|