- 在线时间
- 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:3940376683 ^: n: v; u) Y* D3 e: o
+ {; h/ o' `- N" ]1 D1 G
Hamilton周游路线问题
8 k' X& D( Q" U2 Y4 @
& ^- o% K8 | E O8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。. t' a; u8 I0 p S; x; D3 U
. Z% ]4 p( p \) R" ^6 s4 d
对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
1 A( s( ^% b6 q/ d: F# F6 d
. \9 X0 W6 \1 Q2 I" G6 P9 k
. E# D; t7 E: N6 {" [, b+ V
- W4 `1 T% Y; r. C3 h' n6 O) E//算法实现:9 X9 U3 d/ S3 Q3 q+ Q6 b7 @
0 B; L& y7 z+ P% p `- l#include <iostream>
) N* n) o" G& S! O, O3 W% B#include <fstream>: [+ ?, i3 `6 l$ X6 J6 i( _4 t- f
#include <stdlib.h>
) D- _ t' \' G2 W0 e" ^. ^#include <afxtempl.h> 5 \- i! A/ Q) J$ a
using namespace std;
8 i. D( n5 m: ^7 E6 q. stemplate<class T>7 ^% ~3 ], M( w! b7 z
! G9 ^( K( n& P+ v. Yvoid Make2DArray(T** &x , int rows , int cols ) 2 k; p6 `+ s+ c+ H8 W: B
{ " t, M$ i6 |7 J6 r
//创建行指针 [: M: t$ V- h6 x
x = new T*[rows] ; 3 |5 L8 [. e+ K* `
//为每一行分配空间
' L" \# U' K, F- T6 q6 b' a for( int i= 0 ; i<rows; i++ ) 0 }5 P3 _8 {1 Y) o* X
{
, a$ {0 ~' ~$ ` x[i] = new int[cols] ; 7 r3 _* y2 } L: q
} 4 ^+ k1 }: u. n/ ^' e/ o
} , a. X8 P. m0 x, H$ x. f1 T! @
template<class T>
' J; c' {! u6 A% v1 s
! h+ d. W1 @4 k% ]9 Avoid Delete2DArray(T** &x , int rows) : x5 l# r. J! ^7 E; _; `
{
' P `5 F) @" S& ~7 X& i //释放为每一行所分配的空间
! U' A- \! ^! ]) J) r# Y, u& Z; p for( int i = 0 ; i < rows ; i++ ) ! ]4 d: K6 f$ F+ j/ z* k5 s
{ ) M9 j( Y1 _ p/ r+ \4 q* C
delete[] x[i] ; s# y& m$ {: ~+ i
} ) f2 U% H- v7 o, t2 ^
// 释放行指针
, \: I: M# x7 \* o/ u delete[] x ;
& I: v+ S, O% F; J+ ?: a) N x = 0 ; , o( `/ ?. T8 b' {# z( x- w
}. ]6 |4 B' M, e L- x! I G
5 j3 A" a2 M8 T. V' b8 v m; _: T
//其中,grid是表示整数对的结构。& o \) B5 k7 Q. ?! W! j; A
typedef struct
8 q/ ]& z0 `# j7 `3 U0 a- p/ ~{
8 ~% A+ y6 y$ M2 A6 k int x;
2 R7 U" t9 Y! k$ R3 u int y;
" R5 p! _' f8 \1 y}grid;; T9 p+ V) H8 |
$ q, P, d8 |, |+ F; B! N//用一个类Knight实现算法。1 ~( ^# J7 Z2 X" _8 Z6 ]
& E0 {5 m! ]- ^2 k$ W9 C6 _3 q; M. |* {( B5 s( m% r
class Knight
, W8 o/ F5 e& ~& D7 v{
3 Q3 z% |& o& r6 l$ t% spublic:
3 c9 p9 t4 ^2 W/ ^" r8 P; S Knight(int m,int n);
9 k% k0 B, q8 R) R/ b& l9 m) k ~Knight(){};4 Y" s& g/ ^$ ~# y
void out();
6 H: Q) f9 i1 l9 `" [private:& m1 n2 E2 X$ g9 ~& e
int m,n;9 W) v6 V; O0 X; ]7 G' s
grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;5 R3 {, _. v3 F
int pos(int x,int y,int col);( c. d4 [% G. w0 T0 a- \
void step(int m,int n,int **a,grid *b);7 l/ O# ?+ Y3 j6 J) Z
void build(int m,int n,int offx,int offy,int col,grid *b);
/ H4 j3 x, v4 O. w; A p void base(int mm,int nn,int offx,int offy);
; ?, R( h# ^' v* B2 ?% h9 | bool comp(int mm,int nn,int offx,int offy );
\* U0 x" r: o* r) `5 x4 k};4 [; w4 e5 y) }9 u& s; [- b3 D
; A9 _" y! _1 L0 y
6 F: n0 h( T' t. {& W" Z# a+ e& ^: `2 n3 e" a& F0 Z& [
. U. H# q- V# E) z$ G- h8 _6 \8 J
//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。
% h& t5 ~7 x; {" I- `# L+ 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回路。
4 z+ M7 H$ r( E! t5 ~+ n! }7 L# x" M" A m" `3 u
3 }; R& }- K8 \" H& e' g* j1 `7 J//构造函数读入基础数据,初始化各数组。' `& [7 E7 f5 M7 Z/ f' K) N
% _, U2 {. J- u# a( p) c$ V/ }Knight::Knight(int mm,int nn)
$ q+ Z$ E- S* w: T3 J3 k/ T2 B{, X7 S Q0 l8 o' a9 l# h
int i,j,**a;: e" x m6 P+ i$ o
ifstream fin0;. q0 V- F2 u! u
m=mm;n=nn;
1 ]0 l( t: T$ |; Y8 X' `6 i b66=new grid[36];
. t: v4 A# s4 t b68=new grid[48];
3 X* |$ D- Y% X4 m: D( ^2 `# \; K; m" C5 k/ z b86=new grid[48];0 V( R8 X9 g( \& K l n4 v+ t
b88=new grid[64];
# @; \& T) ^% j! g+ ?0 i" X b810=new grid[80];
( K9 O& T( p$ ^) y x! F b108=new grid[80];
6 V8 d' u+ e7 U3 D& { b1010=new grid[100];5 h3 a) z& ]; T; u# v
b1012=new grid[120];4 F9 o$ W5 S' {- P6 U4 ~2 {% z* l
b1210=new grid[120];
. n, @" Z6 h! V4 ]' H, Y6 A/ | Make2DArray(link,m,n);
! V& A- A3 f' q6 v$ l Make2DArray(a,10,12);) h1 e0 A2 w( n; D( L
% d! y( s+ u, l- ?# U2 ? for(i=0;i<6;i++)1 q' y* d4 j& q( }' J9 n
for(j=0;j<6;j++)
# Q6 H4 Z7 i% ]- ^& t fin0>>a[i][j];3 L+ m3 e: `0 C+ n9 Y1 y$ X
step(6,6,a,b66);6 O) x. C4 j9 q* w
for(i=0;i<6;i++)/ Z. C* X# y/ Z
for(j=0;j<8;j++)
6 T0 I5 y2 K' @) p4 V6 e6 | fin0>>a[i][j];8 A# J/ ]- H$ |7 u0 J' i
step(6,8,a,b68);
/ `' X' J4 i8 S1 T8 ^9 s% s9 U step(8,6,a,b86);
* T8 p: f0 { p7 k0 z; N for(i=0;i<8;i++)
7 b+ i! E8 G. @# w$ y for(j=0;j<8;j++)
* _& O( t( h' `4 C f5 ~ fin0>>a[i][j];
9 F) E, ~ h+ i4 J; [4 M: }1 d step(8,8,a,b88);
+ A7 P* n% i# ^6 _3 F) I& G for(i=0;i<8;i++)
) p/ t+ F$ | M5 N: m for(j=0;j<10;j++)
: H8 ]0 d, C7 v, L j fin0>>a[i][j];8 e0 d7 O6 K; G" u* I9 b5 r
step(8,10,a,b810);
, p- p/ ~- R& x4 l3 v7 A2 G* Y step(10,8,a,b108);
5 w4 s8 K4 q' i+ o for(i=0;i<10;i++)
/ W8 ~$ a- h; R0 F& h' f for(j=0;j<10;j++) : g4 Z4 Y1 _) B$ r
fin0>>a[i][j];) x+ `1 x0 M+ R8 Z p3 x$ B/ `, X4 J
step(10,10,a,b1010);2 g! D0 A6 E4 Y4 u
for(i=0;i<10;i++)' e/ I. f% s' d$ ^! ?
for(j=0;j<12;j++)
5 W5 L- C4 W6 A8 ` fin0>>a[i][j];
9 K* k3 [3 m# d* E. X; w/ A& \ step(10,12,a,b1012);
' B( b' `6 U3 Y step(12,10,a,b1210);- t! A! d! T) r' I: t2 O |4 T6 E
4 m2 y2 M: Z) _' g( f1 Y" V}
$ S+ F7 x+ m- J- M% x0 R
- ]. N& }9 `2 V! P$ V4 A* J! |4 ^1 q! b* W; P+ w3 E
//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。
' L, ?5 d- w+ {- X6 D# z# \* N
7 ]; S9 W3 B- H, D$ c, d1 Fvoid Knight::step(int m,int n,int **a,grid *b)
; }' u7 b9 @# R0 J# r- \{
+ `6 V7 A( X% Z6 A& r( k int i,j,k=m*n;
$ A% A! Z8 w' U/ d7 |+ j, s% A0 |) T# Q if(m<n)6 C$ `! H' X# g1 {
{
6 l- c$ Q/ D, Y! |! K, ?' i. m8 e for(i=0;i<m;i++)
* l* U" J( A. @: t; S for(j=0;j<n;j++)7 Y2 p) A7 U, D) t) G4 k
{8 t+ s, l0 H, P0 X6 l( H/ n
int p=a[i][j]-1;
+ O2 ~/ [+ C( _- A4 d b[p].x=i;b[p].y=j;
$ {. u' |$ \ s+ x }
/ Y2 t# G7 M1 X( W+ k }
3 ~* |% [3 [ J* t* g else{
% w9 e0 l8 ^/ Z% m% w i for(i=0;i<m;i++)
0 C9 d q8 X% M ] for(j=0;j<n;j++){
' U( f a) o0 z+ j4 ^; Y: r int p=a[j][i]-1;
8 b1 S; x- {# T" _ b[p].x=i;b[p].y=j;
2 Q, e* }, O& D% g& b, r }
4 g3 S' }0 a$ K }8 ~, }; }7 W. b; ?( B
}
1 o# x4 r. p4 J6 }6 O6 R3 s2 M) P( K+ }) J
7 z+ ^, V& T5 `# k S$ {$ M* ]6 h
//分治法的主体由如下算法comp给出。
$ G! u/ w( R) Wbool odd(int data) a+ n8 ?# f5 n) T% H. @, e) H
{
( J6 c0 l/ h- N8 U3 U9 f if (data%2 ==0)4 J/ x3 a& Y& ^
{
2 t: ^ T4 J5 A& _4 F4 { U return false;
) R" a0 Y3 B; H+ T; O- K6 e3 V }
% G2 R7 W$ l9 T* M/ W return true;1 Q! E/ \" l9 Q" n j" b
}% y+ h8 ^: `& m
2 I/ x( }! f" @% _. y0 q4 r* t. I- C; |9 n6 D
bool Knight::comp(int mm,int nn,int offx,int offy)
9 D% s) ~7 g* Z5 b{4 _# Z2 `! ?. i/ {' p- s
int mm1,mm2,nn1,nn2;9 [5 M( Y) l. y. U* }
int x[8],y[8],p[8];# M0 R+ T) a+ [* ]8 c. [
if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;: Z+ d8 v" [& `2 y+ H Z2 p, Z
if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解" C( a8 h$ ^7 r3 y
mm1=mm/2;8 ?6 ?3 V" Z: o* u+ Q y& U
if(mm%4<0)mm1--;
$ R7 v# [. O$ l" X3 v9 x1 G, K- F mm2=mm-mm1;
6 Z; {8 E2 x3 h nn1=nn/2;& H# U3 g: }% _7 b* R! [7 N" p; ~
if(nn%4>0)nn1--;4 L- ~6 @: c; {4 C" ^! O
nn2=nn-nn1;
0 f0 }" E8 J# |- f, Y //分割步
4 o* }/ v0 i8 K' `% b; A o comp(mm1,nn1,offx,offy);
: l; @' S% _" }1 V! M: Q' V. b comp(mm1,nn2,offx,offy+nn1);, E' H8 v6 Z; h. i5 u( j& ]3 k; U
comp(mm2,nn1,offx+mm1,offy);
) ^$ C2 }$ e7 q$ B comp(mm2,nn2,offx+mm1,offy+nn1);
, X9 _4 _- ?6 u( ]- ^7 H* f, x //合并步
$ T0 N) q3 O% l4 h x[0]=offx+mm1-1;y[0]=offy+nn1-3;
2 c( F3 J" e u x[1]=x[0]-1;y[1]=y[0]+2;
0 B) o; U' a( a5 O0 [ x[2]=x[1]-1;y[2]=y[1]+2;0 x# c4 T4 Y& Z. u# P# G
x[3]=x[2]+2;y[3]=y[2]-1;
/ t7 J$ I; T, V! ~# V; v x[4]=x[3]+1;y[4]=y[3]+2;
' e; S' T7 q5 ?+ K6 r; S x[5]=x[4]+1;y[5]=y[4]-2;
( Q( ?. L: R/ a9 [5 l, L. f x[6]=x[5]+1;y[6]=y[5]-2;
1 _: a5 P6 `- _ x[7]=x[6]-2;y[7]=y[6]+1;; U5 {$ f5 u0 f) w
( R7 z- O$ C& ]8 n0 Z# @4 k- f for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);7 e( O4 H* o1 B/ x' `* u& P) A
for(i=1;i<8;i+=2){2 S9 H7 V1 d5 U/ w/ v: a
int j1=(i+1)%8,j2=(i+2)%8;& L1 v% V0 s9 b( i- t4 j
if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];
# x# Q+ @4 p6 z# g: a! u" P& G else link[x[i]][y[i]].y=p[j1];3 b: L8 g: o/ Z( a3 c( Q
if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];
) j. l1 W" g- G+ M else link[x[j1]][y[j1]].y=p[i];
2 `3 l- ^! @! u }0 M4 n6 k# D s: ~- ]5 F) b1 j- Z
return 0;+ A) F1 X7 Z) M$ K
}
* [8 T( q' h" ?+ ]$ O3 o4 M# E, I( c% J! |6 t2 f% ^ X
0 T4 ~3 _$ V8 E9 C! f//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。
' o; k4 L7 |) c/ q% U! @7 H/ y9 h
) w/ r: v) [7 M4 {void Knight::base(int mm,int nn,int offx,int offy)
; c; u0 a/ B) t+ p3 d5 j{
- \- i- z7 j9 {2 |; r4 a if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);
}% W+ l! r" p1 v3 ?2 h, V6 n if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);" D% u, q; Y5 t% e. g
if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);
& A" d& J4 U( N* ~1 D if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);2 r* g' ]( }$ h; p) }
if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);
' V/ Q1 z: P4 k3 f/ W5 O if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);7 @" l5 J7 N% q& R+ b
if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);
. G4 U0 k, @/ Q& T if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);
4 e& F0 ^$ ^+ k if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);$ {; V% }7 L' J- X$ S8 {) H
}6 L) i Z8 Q+ x, |( F; b t
. e) j; m9 X4 e1 _# z) `
# w. j; u+ E7 _6 Q4 C
//其实质性的构造由算法build来完成。+ \- D& Q3 M6 r3 |$ z
! z$ u# ]4 q0 v+ p$ R8 d+ Cvoid Knight::build(int m,int n,int offx,int offy,int col,grid *b)
/ ], I4 F. b2 R, {( G{
5 V- ?* B$ P7 J( n: K8 I int i,p,q,k=m*n;
O0 Q& ?) n! `3 g for(i=0;i<k;i++){
$ f0 |. ]# [& o! o; J int x1=offx+b[i].x,4 D O7 L: {% V( N
y1=offy+b[i].y,$ M' g" ]$ `2 J5 n, v4 E3 L
x2=offx+b[(i+1)%k].x,/ J+ s. {% {: |% t- A$ E" _
y2=offy+b[(i+1)%k].y;
q8 B/ _/ }) w+ n' I p=pos(x1,y1,col);q=pos(x2,y2,col);
8 d/ e2 B( \! Y9 \$ E8 A/ r1 g3 G link[x1][y1].x=q;link[x2][y2].y=p;
6 n. E0 {" H7 X# G* K } . Q! h+ O! ~) `+ |: x
}
" x% g# a9 P: D9 ?* a9 A: B
' F0 h8 w% A0 ]# p0 C
4 T, s" z' `$ o' @. D! b; m//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.
3 Z* [. A, Z+ ]$ k2 F9 }8 ~/ d4 w' ?3 |* P s1 y3 Z, x% Q
int Knight::pos(int x,int y,int col)2 q9 f# a9 s4 I% q% `
{
! }, F$ `: ~ f& S& d return col*x|y;2 N3 ^% r, y6 C2 F
}
3 F! d% i F0 j b( c# Q
6 P. T& j( w3 ^# k8 r
- m4 K @. o3 N+ p' a- l6 @) h//最后,由out按照要求输出计算出的结构化Hamilton回路。( A# T g1 h; m$ C$ M
, `! p0 N5 F" [ Q( u- B% j; q
void Knight:ut()9 c3 g0 Y/ F, o* l
{1 w) L* Q! m6 [( o
int i,j,k,x,y,p,**a;" V/ O, L, j7 O) s
Make2DArray(a,m,n);; n! b2 S2 i, R V
if(comp(m,n,0,0)) return;1 f% x3 L' d1 m9 f& f
for(i=0;i<m;i++)
6 Q! N# R) {' g4 E for(j=0;j<n;j++) a[i][j]=0;" M4 P! U& K5 b7 t! j' t
i=0;j=0;k=2;a[0][0]=1;
, \9 J: T7 Y( J P- i cout<<"(0,0)"<<"";$ B' ]& O, e, ]( |2 ~
for(p=1;p<m*n;p++){1 [, _7 Q5 c) A N2 h. q1 e' g
x=link[i][j].x;y=link[i][j].y;
9 g) F' B9 r* c: h# B# J3 N, r i=x/n;j=k%n;+ X0 B: A! o8 ]$ P: ^
if(a[i][j]>0){i=y/n;j=y%n;}# @+ U0 T9 q: `9 ]
a[i][j]=k++;
3 q/ p3 J# r) z; {. E1 h cout<<"("<<i<<","<<j<<")";% p% ~# d* ?% ]9 q
if((k-1)%n==0) cout<<endl;
8 r! z$ R/ l% y! v+ P/ y9 ~ }
7 x6 Z! j3 |: g cout<<endl;
4 o9 \$ i+ p2 n4 b( f6 S3 `8 X for(i=0;i<m;i++){
- y) z2 O2 c# \1 h& u for(j=0;j<n;j++) cout<<a[i][j]<<"";
& u. U& s% {9 n0 B6 n0 K. ^ cout<<endl;6 T+ ~5 r) U! U8 r! i% T
}) i9 X0 {8 C( C, T) ]0 A
} |
|