- 在线时间
- 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: ]8 e" x8 l7 a% X3 [7 }
3 Z8 V8 Y$ i1 m# k Hamilton周游路线问题$ A( k; B0 y6 U' h7 W: ~
' ?. V, j1 ]/ P) W; A8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。! ?! @* L% U# _( X( W- h9 G$ }
& i( @4 ~- ~- o# {0 `) ~
对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
3 ]5 ^; u7 T/ K. K" ]! P2 l7 x! @ `; n( z' i9 z
$ Q6 A+ b% v- I% C$ H
& e' Z1 ^2 C) o$ j: @- u- W
//算法实现:
/ V# X* V. U6 `9 O _* Q$ M
9 P, { X$ Q# v8 G" \#include <iostream>
8 o* G* f& K( v#include <fstream>
0 x. @) S) f9 E8 i% `* z# G7 {; G#include <stdlib.h>
, c! y% s; W0 k3 d* X' X#include <afxtempl.h>
- |7 E$ d/ A y ?using namespace std;
8 X2 O' a! H5 ]1 ^; H' J' Wtemplate<class T>0 V# ]+ |1 ~- z! F: H; f
* l* o, _# A2 G
void Make2DArray(T** &x , int rows , int cols ) $ b. o' K' X2 r, t/ U; Y
{
5 j0 z3 i8 s9 D //创建行指针 2 ?: @: P2 C3 z) ^% ^8 \2 B
x = new T*[rows] ; 7 G5 z! [; L0 L" s/ b
//为每一行分配空间 # s* h! o$ P" f
for( int i= 0 ; i<rows; i++ )
5 G6 g' P" l/ B" ?- s: O* f- M { # K+ q- E6 g8 L, P& a1 }
x[i] = new int[cols] ; 3 i x! k# \0 `, |% k# U% ~ [
} - U" I& _! ~3 o u- N! X+ @, I
} - C$ [6 |/ H, C3 |$ ^
template<class T>- r# S! B* r8 v% m5 p6 y
* D( L: Y0 q E2 k- r$ I
void Delete2DArray(T** &x , int rows) 8 b! F6 y# p. |/ E+ F: y+ V
{
6 y7 b1 @. ~3 B0 D$ V( B //释放为每一行所分配的空间 6 U% W# P8 A! P* j1 k
for( int i = 0 ; i < rows ; i++ ) : X0 s7 X! ]4 {
{
: d# R, y3 C, \ delete[] x[i] ;
1 H" N( L+ Z) ?: w } ; \6 H& c, F4 s: J$ u4 J" \
// 释放行指针 ( `1 H4 i6 g8 B) c
delete[] x ;
/ O% L0 v. j0 I& S: f* O, B( o- i) j x = 0 ;
6 }, e) N* |$ _& Y: k* B8 L2 u}8 A# X7 ^6 I2 a1 W5 j
% ]+ P9 V3 ^0 L* G; n% y0 p! o
//其中,grid是表示整数对的结构。! k$ c# r8 t; x4 Y/ n8 I0 Q
typedef struct
% ^! K4 M N# X{- \; C. [8 R$ a$ P u f
int x;% b% m- c* T' J) [, y) p, \9 Z
int y;* K" [& v% k" c' y* K* A
}grid;
& ]5 U) A0 S+ m' j( T ? R8 C6 P5 _% @! a$ h. G( m4 i& F
//用一个类Knight实现算法。
; Y3 i5 z& H' |- o M0 b6 Q8 _' o
4 H% P+ K2 L9 o9 O. [0 g' u# a" b1 b, X# X+ ?! s9 w
class Knight
$ C& X- S- N2 r' l! @% @3 Y" l C{
1 y7 D6 m8 C$ H$ d% F f7 M+ zpublic:: @5 x4 n# y# k2 T
Knight(int m,int n);
e; K5 m) T9 P- Q( [ ~Knight(){};
: ~% i# d% p! e" R# m5 O8 f void out();8 n6 S" ?- \; _6 w1 W1 m
private:# l. B5 y' }( A# ^/ z
int m,n;
! ~5 k+ t: L) |) V' H2 U. a! H grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;
% s+ |4 X% V! x int pos(int x,int y,int col);
( K+ }0 K; _ R, H void step(int m,int n,int **a,grid *b);) Z( R. E6 R0 _2 V/ }
void build(int m,int n,int offx,int offy,int col,grid *b);5 l$ @ Q) U% f0 {% x) ]
void base(int mm,int nn,int offx,int offy);
& ~' P7 S7 N! y2 x bool comp(int mm,int nn,int offx,int offy );: z: G" ^7 X, F8 v* X
};
r, M4 d) @& ?2 Q$ Q3 I. a* c3 c/ C* [
7 d$ N: E+ a" V1 A' i! C0 G& I
7 B4 h$ O! ?8 x, O, V2 c
1 ~9 B- @9 R3 F( C4 S9 i' g2 U2 b6 q; G) M$ P4 y
//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。
* m: K3 q7 F* L! h+ C. Z- L4 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回路。, E+ ^9 ^) W( X+ k
6 \: f! F7 u( _. r
& d) H6 z0 d: ?# c2 d/ n//构造函数读入基础数据,初始化各数组。
! ]8 b1 n5 X3 Y( @" H, Q' V. K( g3 k0 y! c, ?. {
Knight::Knight(int mm,int nn)
4 \! L$ \; E7 H* y8 _" L3 c5 p{
3 U z4 i& a4 d, v9 e# U! d( l int i,j,**a;2 F& E- N8 Y+ k8 P' ]9 e- a: I0 U
ifstream fin0;
3 Z* r, Q' Q- p m=mm;n=nn;" I3 G) r* p2 ^9 J6 s
b66=new grid[36];
4 d) T1 W/ R4 L1 Z b68=new grid[48];
( m2 L$ x' J4 T8 g b86=new grid[48];
, U; a0 X! z$ D* O @+ v- `( G b88=new grid[64];
/ I3 \' u, q9 R4 |% j; o5 k b810=new grid[80];
1 b& a1 V' U8 x$ V9 J) a* d b108=new grid[80];
7 G& q# l, \, d* M# C. {6 Z. c. o b1010=new grid[100];
( ~7 |9 ~6 R0 Z4 n+ f) y b1012=new grid[120];* m' e, o' k& j5 V9 k N
b1210=new grid[120];
, Y) h: u4 J/ \: s. A) V Make2DArray(link,m,n);
' l6 A- a3 F0 S' ^8 u" Q+ x( [7 u, f Make2DArray(a,10,12);# |( S4 w/ t) w! R' u! I4 ^
: c5 }( N9 ?) k( a for(i=0;i<6;i++)1 @4 X* ?% X6 S% x
for(j=0;j<6;j++) 6 M- P6 C J! v- B; @
fin0>>a[i][j];& O0 o2 M# L: m+ U
step(6,6,a,b66);
3 C4 z% |) p V* q# X for(i=0;i<6;i++)& o2 X" Y" n( n1 R! C
for(j=0;j<8;j++) + n& w' {' p+ a3 u2 C
fin0>>a[i][j];2 q+ l4 J) A- }4 k; |9 j; c, M
step(6,8,a,b68);
3 B- a" G% H$ U" _ step(8,6,a,b86);
1 [2 z# ]8 s: G) `6 F5 k for(i=0;i<8;i++)
S! G/ w) Z! @+ ^# O for(j=0;j<8;j++)
) r. u- s2 v: d6 m fin0>>a[i][j];
# {7 u7 P- i7 `+ n2 C% J3 I4 H step(8,8,a,b88);
: K' B: i+ u) y3 O. I# J for(i=0;i<8;i++)) Y; D2 V3 `7 S7 h
for(j=0;j<10;j++)
5 n4 S$ N% L+ c* w# y: S0 d fin0>>a[i][j];
5 { P! R4 x" [) M; Y$ ? x step(8,10,a,b810);
4 R& W7 f0 @3 j4 ^ step(10,8,a,b108);
3 i% [) h3 s' _: o- A1 N7 b2 m for(i=0;i<10;i++)# A* C+ E1 L, X' n w
for(j=0;j<10;j++) ; l8 y3 R6 E( _& @5 p& V( N3 f
fin0>>a[i][j];8 a* c. E9 Z' l. \ E" Q. U! j
step(10,10,a,b1010);
! v% s1 W$ L& {6 | for(i=0;i<10;i++)
) U4 C5 z1 l, l( y1 o for(j=0;j<12;j++) 8 V8 C' o$ c' l$ @7 {
fin0>>a[i][j];* R3 A8 E. z* N; M7 X
step(10,12,a,b1012);
% r% P1 m. x+ p7 J2 I; r/ }: S step(12,10,a,b1210);5 C# S* g8 \1 \# I9 K) ^
' O7 V8 S C6 D4 ]4 z; P. _}
* j p W* o7 B8 p: X1 `
( \3 i' ^) w2 C: b4 I
9 e5 r0 X/ ^2 J//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。
$ I( w. |8 y. G2 O- a
* |: s, _0 y8 G `9 U, Q1 U. {void Knight::step(int m,int n,int **a,grid *b)4 v: r2 @) E& X% P; |, L
{# ]7 A# {1 ^& P! r+ s8 c( Y
int i,j,k=m*n;: |; P3 J% }' |2 A
if(m<n)
( S4 |0 g" ]' D" V& h, H {0 o: }6 X9 V( \& ^. z$ [' P G4 M
for(i=0;i<m;i++)
( [% n# _' c" r* u. s for(j=0;j<n;j++)
3 ]: t8 R1 `. A' Y9 o0 q$ p {
# w) j% h/ f% s7 x int p=a[i][j]-1;5 u0 P# D+ e7 K8 i/ C
b[p].x=i;b[p].y=j;
4 V& i/ ^) F" v }
, @& u; f1 w3 F! N( y7 W }: R4 f2 W! c5 ~5 }7 w- E; u7 F
else{9 U8 f: M8 y R3 v5 }; I* J
for(i=0;i<m;i++). Q2 k! X- C# v r6 B/ [
for(j=0;j<n;j++){
I& c; j2 s4 g4 C5 t int p=a[j][i]-1;: s2 a8 \ _/ C6 r
b[p].x=i;b[p].y=j; : K/ m% G% L% K# b- l( f$ C' _3 k
}
7 x+ e8 y: b) c; @% a y7 @ }
/ k7 n- M* B: @ B- D}3 n, e: m& n" a b- ^' g
8 F8 c) w8 K. ~7 {( `# u" }# h0 A) x! p9 _
//分治法的主体由如下算法comp给出。' z( Y9 x- ~ `4 S' }5 b
bool odd(int data)
$ o0 V3 s2 g3 r( T6 H$ X* Q{
- p# H: c$ a& b8 L- ]" E if (data%2 ==0)
+ b0 ?) X1 [: U+ t6 | {! C7 b4 F/ h# U, R1 I: \
return false;. Q8 F) s3 ^ m! _8 J6 R- B
}
3 x, q4 X3 M& A return true;
0 S2 o( J Q3 ^% E+ W}
4 E! c9 H& Y! d; G) X0 R! T! E3 d# u9 y( e% W/ k4 p# v0 N3 l
# o; g7 [, v, o& s; vbool Knight::comp(int mm,int nn,int offx,int offy)
, f, m2 Y- v9 w3 Y; F; d+ p; D* P) J{" D i, Q/ t4 m3 T1 ]
int mm1,mm2,nn1,nn2;
5 D1 i$ p, { B. `+ p! o int x[8],y[8],p[8];
6 U- i( N4 E0 Q- }" u% m if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;2 I2 P, G" W- O0 Z
if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解
* R2 C, x3 z: A9 b mm1=mm/2;
3 z0 J0 ~* r( K7 r1 t' P- { if(mm%4<0)mm1--;
4 |( c: K% H' M, s+ t3 w7 ] mm2=mm-mm1;
6 s. m) i& } r( V: ^* v: g# _ nn1=nn/2;$ v3 q R$ e: j1 p8 a
if(nn%4>0)nn1--;
8 y) G% G6 h# v4 S nn2=nn-nn1;
# E9 k/ m4 Y; r5 Z3 z; R y1 o# I //分割步
0 `3 H) B q+ W; ^+ y: _, y comp(mm1,nn1,offx,offy);
/ I3 I3 H* Q* ~* O* f% D comp(mm1,nn2,offx,offy+nn1);) n+ r& K8 e& s5 A
comp(mm2,nn1,offx+mm1,offy);
, z+ I6 C# S8 Q+ C/ S4 M# M" J4 _ comp(mm2,nn2,offx+mm1,offy+nn1);0 k) a1 o5 Q8 Q! T3 W
//合并步* F5 n8 O, K O! v& n. o) }% ]
x[0]=offx+mm1-1;y[0]=offy+nn1-3;/ r9 v( c2 H; t2 z( \; P+ l2 _, P
x[1]=x[0]-1;y[1]=y[0]+2;) P: N7 g* p* \( \; L7 x h
x[2]=x[1]-1;y[2]=y[1]+2;
' i' r* [- |1 O0 b! v1 I2 } G x[3]=x[2]+2;y[3]=y[2]-1;9 n7 t; ^6 `9 `1 ^ N
x[4]=x[3]+1;y[4]=y[3]+2;
+ }" Z& g, f a3 S' a7 o x[5]=x[4]+1;y[5]=y[4]-2;
6 `! @+ s: h6 a0 \0 S& g x[6]=x[5]+1;y[6]=y[5]-2;6 y, l$ f8 S8 u9 M
x[7]=x[6]-2;y[7]=y[6]+1;5 [/ x2 \4 F& E: v# H
# B' Z% m& R& T" p3 A7 k' b1 e* y for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);
1 b$ d/ k1 T) v9 H. m/ U for(i=1;i<8;i+=2){
( m! I8 g5 h* r+ C I/ J int j1=(i+1)%8,j2=(i+2)%8;
1 [7 h" D1 X7 @9 m4 i& z5 t8 @ if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];
) S7 U/ ~5 }) _" p else link[x[i]][y[i]].y=p[j1]; ?5 | A* ^/ m1 F8 {4 J/ F
if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];
& ]$ d+ D9 J4 K. h; z else link[x[j1]][y[j1]].y=p[i];$ p2 o/ A1 T2 k5 ]& @1 {; B5 k% w
}2 B" M7 J0 i, b5 n$ a0 o
return 0;
8 `# f- f# d5 U) k- S2 T}
8 G# [) i9 D+ `4 ?4 q7 f* C( a- X
5 D4 U6 I6 z, n5 u4 q8 v: K/ I: C# E7 X) V1 a
//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。; B/ y1 O5 F3 I* O+ j6 e' _, D% B
" y7 w* }3 {! f P
void Knight::base(int mm,int nn,int offx,int offy)
0 [) h3 }: w) t6 u/ p) h* r{, E" R( \/ c" m, K0 E2 h8 n: C
if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);' \( K+ {% o+ S3 v0 l- O1 l
if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);" T$ m7 s/ A; Q
if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);' J# B( L9 t$ x6 Z
if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);5 h; S, w9 i; \* b& P" t$ D; ?2 f) k& H- R
if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);
, z- m; ]( f; k' u0 R& R4 ?' ]$ ^ if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);
, u# S1 I: ?7 T if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);& y7 G1 G ]1 m
if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);' ^& Q8 S& d: d# R k, H+ l
if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);/ P' j+ D! A" s- p! r
}
& V( s% q+ Q% G( s+ N
4 B" M1 n/ T2 m" } g" Q# t* n4 b4 \
//其实质性的构造由算法build来完成。; _5 B/ K* r& I! V' q
! m" B' v9 i" x
void Knight::build(int m,int n,int offx,int offy,int col,grid *b)/ B) S8 y+ E8 r! v8 s4 G8 k
{
* ?, v+ C% U6 ~ int i,p,q,k=m*n;3 z- `! e l, K& {
for(i=0;i<k;i++){4 v# L4 [. @6 e0 c5 D( w
int x1=offx+b[i].x,
. O8 z6 f) W$ d+ x2 y+ a, m y1=offy+b[i].y,$ v4 M8 s. O& Q8 t' X' I' y
x2=offx+b[(i+1)%k].x, r, ]- `+ [9 b6 z5 C: ~3 h
y2=offy+b[(i+1)%k].y;
4 O4 e# Q/ P3 A$ D p=pos(x1,y1,col);q=pos(x2,y2,col);
V6 I! t* s% k( J9 L* ]: K9 f# G link[x1][y1].x=q;link[x2][y2].y=p;
: G$ [! O5 H, M+ z% F7 I" b } % g/ u1 f i, I. Z
}
2 r- C" m* B5 I! _
& b Q- h4 ?% h/ j K! Y2 d+ t
r/ [1 I7 _! R1 L- \! F//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.3 p) g! K5 B8 ~/ h
% @7 F& Z9 [) X9 C
int Knight::pos(int x,int y,int col)
8 U4 U( C" t$ i- m( \ g{3 U! f2 d$ @5 `# \
return col*x|y;9 a1 z# I1 W3 A6 J6 V
}
, s% Q b8 A7 ]- y1 j2 c6 L0 i: S0 T) Y" B% I& x( x# X+ ]# g. c
Q n9 x0 o- W//最后,由out按照要求输出计算出的结构化Hamilton回路。
a9 {4 [ s' W/ x
/ x/ g; d! x! Y- a( hvoid Knight: ut()
) r! @! J9 d5 s( x- O& A{( T4 a i3 ]) o+ R' m
int i,j,k,x,y,p,**a;; {; }7 D ?$ l8 q }
Make2DArray(a,m,n);
: d& F* h+ p+ P if(comp(m,n,0,0)) return;1 t0 H* }; n9 M
for(i=0;i<m;i++)2 }: X& v) h* g- H
for(j=0;j<n;j++) a[i][j]=0;
# D5 k& Z! s- v$ @6 r i=0;j=0;k=2;a[0][0]=1;" X8 f' ~7 K+ {
cout<<"(0,0)"<<"";1 x) o7 x9 z* _1 {& z A% Q
for(p=1;p<m*n;p++){, F% U2 Q" j4 U' J
x=link[i][j].x;y=link[i][j].y;
" I4 R1 J, O2 F1 b i=x/n;j=k%n;
; G, \; {3 ]; L if(a[i][j]>0){i=y/n;j=y%n;}
; R3 ?& k% A0 j* J3 ~& M a[i][j]=k++;
; R# Z# m. s0 o( f cout<<"("<<i<<","<<j<<")";% p) X% I$ @) r. P1 Z2 s
if((k-1)%n==0) cout<<endl;2 ] v; B3 Z2 ]7 B; D& M8 ~
}
& [- r" o E w3 p cout<<endl;1 C4 m8 L$ g0 B
for(i=0;i<m;i++){" v) w: j# B2 G
for(j=0;j<n;j++) cout<<a[i][j]<<"";) U% c$ ^7 Z1 e5 B# w
cout<<endl;- V7 p8 e: w% P1 T3 f. n
}" R4 ?* t0 s2 W0 ]
} |
|