- 在线时间
- 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
5 T; N% `! O" @) k+ O( C7 F/ \* M4 ^5 J
Hamilton周游路线问题3 [3 [4 T. l" u7 n
# ^: a- K/ _" N0 H2 T
8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。
$ Q/ f1 ~8 P$ c0 T- Q8 m; ~, Y! g0 p' V
对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
2 j' L/ Q* v5 a$ |8 \# C
2 H9 x, X+ E+ {
0 L0 Q2 X6 x' ?3 t6 o1 w2 F& `7 E: S( u. b# D# X- n; \
//算法实现:, d! M% }9 f4 P# _ \( R b
% u+ D+ ]9 o' }, Q. G8 w
#include <iostream>. V/ X. p, b! u. s2 a u
#include <fstream>
# `7 v% N2 R' W$ B#include <stdlib.h>3 V/ X$ Q4 Z8 w
#include <afxtempl.h> 3 q/ X7 I2 E- N0 O- D( X# ]2 U3 s
using namespace std;
5 }/ q7 X3 M6 ]+ r, d. I) Ptemplate<class T>& V: ]; `7 r# O" v+ E
- ~" d) M& x7 @ p$ V: s
void Make2DArray(T** &x , int rows , int cols )
/ P' y% a7 B' P# `+ ]{ # }1 q! g# P, O
//创建行指针
! q( B9 J9 Q. l% _8 ~8 {; ~# o x = new T*[rows] ;
# G/ }- F* ~" E# j" O7 J6 Y3 e2 P5 r //为每一行分配空间
7 }8 ^; e3 o$ ?2 @) J! w. f! K for( int i= 0 ; i<rows; i++ )
7 j; f' Y+ \, N5 E6 L1 }: j# C { ! t& @- d! j5 y8 e% V: k% L0 f
x[i] = new int[cols] ; $ }, u4 B! ~1 \+ n4 v2 ^
}
) \$ P! L$ w( L* h2 b} + e2 b! A+ O7 o5 {2 G
template<class T>
6 w9 [2 R9 u; {
$ t& f. i5 q F* s& Kvoid Delete2DArray(T** &x , int rows) / g, t2 U% a' d- J
{
8 J" H+ I3 {3 L3 H1 O) P //释放为每一行所分配的空间 3 r- J& k. U; \4 X5 r
for( int i = 0 ; i < rows ; i++ )
$ G5 v( d* a6 ]& Z" z e {
5 _: t5 H# X9 ^! v2 e delete[] x[i] ;
3 e* X, \3 l# ~9 T) t, N% U) Y }
3 k& K! b8 k2 \, ?% p // 释放行指针 ) b# |8 }2 v2 D. R: H% r
delete[] x ; 0 T: t: R3 S! S# p
x = 0 ; 2 ~) K" p+ r# |( \
}4 s1 H0 ]% \! ]: [0 Y1 j' p
( z( y# C' v, r8 X: W- n+ Z//其中,grid是表示整数对的结构。
- C1 s) T& E7 r6 \% j8 B# o+ Ktypedef struct1 G p; a8 j3 d1 P" @. G
{
R. h- |: V7 [ ]4 x6 X ~ int x;- ^, B' \( T8 r) r" _, k
int y;, [$ D! [% c$ @
}grid;
8 r" s' b' ^7 F- X: T
& Q6 u/ E9 @1 k5 r6 S% B. k//用一个类Knight实现算法。
/ C# c" Z( f& j5 W! u0 X/ \0 A6 g& m- I) P: B
X/ V) @7 _* s% @+ J% l- X9 r( s
class Knight* k1 t- Z* z% E# i8 v4 `0 X# L
{
2 E6 ?9 M, ^0 {5 l6 tpublic:$ l: ^6 E! w, U) B6 ^+ }! n) i0 M
Knight(int m,int n);+ |' a# Y1 R( z" ^' R3 S! p9 v
~Knight(){};5 J: a) Q6 h; o& q; C6 W
void out();+ e4 _) |" d. V& w9 ^, ]3 y
private:
$ G) {% I( v1 c( L int m,n;4 i7 s% P3 x9 i4 t% ^
grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;
+ F0 _9 _+ \. S- B' U# L7 f9 w int pos(int x,int y,int col);3 N0 P' z* Q5 W4 _4 h# ~2 o
void step(int m,int n,int **a,grid *b);) r7 @! v: @$ n& e: P) W
void build(int m,int n,int offx,int offy,int col,grid *b);
( Y- n6 f; p, R9 m void base(int mm,int nn,int offx,int offy);- {" v2 H4 \& f
bool comp(int mm,int nn,int offx,int offy );
: D5 p; F! h8 c5 g$ x};
0 N) {9 ]7 U* y% ~ R
: A0 e2 R# z( G' a 1 [7 }$ a3 i3 ?8 ]4 q+ H
. ^; u* r2 x8 N4 [3 C% ^. O1 p" V, r8 R: Y- z( v: o+ F c9 t
//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。
) l4 c# j* y* y9 ^7 t//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回路。$ g/ m: f! m$ {9 V5 k! ]; G" V- M E
0 z0 [& p, t: l7 P: Q6 u1 J
$ W0 z3 Z2 z* P% @/ n: A* {& R: S* b
//构造函数读入基础数据,初始化各数组。2 V- B; B! | y; d+ x0 \% U7 t
. ]3 k, T! C0 b& |; A9 hKnight::Knight(int mm,int nn)/ T" Y1 {9 x* S& F. m6 Q
{, w/ g k& W3 ]) b
int i,j,**a;* @' r) Y; N! s: x
ifstream fin0;
$ C$ [6 R& z' N- q0 H m=mm;n=nn;. p7 w5 Q m; L7 K Y7 ?! T0 c& |
b66=new grid[36];
( G+ }$ s/ }6 v; J W b68=new grid[48];) g5 [( u6 r0 t5 q% Y
b86=new grid[48];
1 G/ x W3 O [9 X b88=new grid[64];+ G4 [: O5 P. C; U
b810=new grid[80];: [6 A/ r$ k+ Z$ i- B: Q9 s) B8 i
b108=new grid[80];
6 Q$ j) y" ^+ E! q b1010=new grid[100]; ?4 k2 ~+ j6 p! N c) s
b1012=new grid[120];. ^9 o' v& x2 O7 R
b1210=new grid[120];/ L- s6 ]* }& P8 k
Make2DArray(link,m,n);
* R9 N$ D7 Y' [5 @8 [! ` Make2DArray(a,10,12);
/ ?; `" |# [) w" G w" p
D& B" V* A$ h. `4 J# o; O( n. z for(i=0;i<6;i++)
: V# _# X2 ^; T. q o+ i1 W3 m for(j=0;j<6;j++)
% Y6 b1 \! r! l( b fin0>>a[i][j];8 G; F, w* g* _ ?5 e; h
step(6,6,a,b66);0 Z" H, R: a$ U0 G- f* S
for(i=0;i<6;i++)
* z0 b; G0 F5 z6 b4 j for(j=0;j<8;j++) ( J4 _; W1 ^) @+ o* L$ ^$ G+ O
fin0>>a[i][j];
+ G+ ]9 n' D1 R% ?. @- J step(6,8,a,b68);0 `& a7 Q% y4 E% C* Z
step(8,6,a,b86);5 d: z x5 w9 f! _
for(i=0;i<8;i++)
0 d" b+ E" n, f for(j=0;j<8;j++) , B" j/ e) J f y; i& [0 z
fin0>>a[i][j]; W G& Q) j+ U; ], H j, u
step(8,8,a,b88);
- p, [4 t, d% N4 k for(i=0;i<8;i++)$ x, Y6 ~7 p$ w7 {# U: d
for(j=0;j<10;j++)
) ?, C& ?" m3 ~; s$ P fin0>>a[i][j];/ E& b) x) T% @! C
step(8,10,a,b810);8 s# W# m3 m. a, \$ _2 J
step(10,8,a,b108);7 X+ F( c$ r. b: n# T( `0 \
for(i=0;i<10;i++)* a" g. d% h. N" y: `
for(j=0;j<10;j++) 7 X- h3 f/ U) o" I
fin0>>a[i][j];
* {; e: P' C% ~9 g+ I P step(10,10,a,b1010);
$ ?( w' q4 Z* H6 f4 s for(i=0;i<10;i++)5 d0 x2 w) I/ |8 b+ {
for(j=0;j<12;j++) $ ~$ s' M* i* x5 `7 l; G$ v& V. c
fin0>>a[i][j];
Z( X0 K2 E* W. K5 F0 }- | step(10,12,a,b1012); t( v6 Z' T! {
step(12,10,a,b1210);8 H* `9 }7 D. R( p+ H' Y! \
7 M; y0 g5 D# x/ u
}
5 P- X1 O: }: T5 j- ~6 E
+ j, D/ |% e1 k7 c5 b/ U
' Y* q! k% o! x2 n+ C//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。% j/ ~& v% ]0 _; g8 j. y
( J& o' H2 m# W
void Knight::step(int m,int n,int **a,grid *b)& b, \. C# {9 a" {6 @
{
" s6 B% H0 `* H+ u) U int i,j,k=m*n;7 K" F1 z* r3 z8 ~, g
if(m<n)0 ~# \! s2 m3 X& F6 W3 _. t
{/ b }) j8 v9 D- N
for(i=0;i<m;i++)/ |5 E4 ~. C4 ^/ e
for(j=0;j<n;j++)
! B4 F& i' ^! a" B0 ]+ C: F {
1 z" `4 C: {% Y2 j X int p=a[i][j]-1;
5 X) W- n: y7 {! f5 }' Z5 E& w b[p].x=i;b[p].y=j;4 Z+ a' \- Q4 @1 _0 J/ C
}& e- w0 G4 i- |( |
}/ g5 I3 o* C$ Y, S/ ]* o* i" o- H3 M
else{
) B) l! Y, o# M for(i=0;i<m;i++)
2 v G: H- y5 e for(j=0;j<n;j++){
# Z: s# k# n5 s$ r7 Y6 z4 Q int p=a[j][i]-1;. ?# i2 B" v& C7 A5 S' ?
b[p].x=i;b[p].y=j;
2 y& f4 [1 {# R' S( ^- s9 B3 b) ^ }, z% u+ k/ h; d* x8 d& f! {# ?
}
; H# v4 `- \: q; o- C9 }" N7 u}! g2 W% R' B7 k3 W. m
5 ?9 D6 r! ]( [3 _
: c( a$ ~" D/ w//分治法的主体由如下算法comp给出。
" {" F! P" t0 F" lbool odd(int data)
0 ]1 {, |5 H5 d6 ?- a k5 Z{
+ ^& a2 ^/ R, }( n/ O: C if (data%2 ==0)
# ?& i) \8 l# |, c3 X3 e9 v, r {7 A3 i# W3 a4 J
return false;
, i1 B+ W5 ?+ d. u) B3 V, v }/ B1 F& _3 c8 F* I4 Z
return true;
" H/ a, [0 y2 j4 I" |& Q' `}- z' t4 m. U0 D. \1 e: I. V
+ ]: v2 e, b: W- M7 J, r) Z1 U. g
+ E2 f8 c: z. e- X6 j Hbool Knight::comp(int mm,int nn,int offx,int offy)
5 K% j+ j# X5 H{$ J9 E5 G/ R+ {. ?: k
int mm1,mm2,nn1,nn2;, o5 d0 `! C; w
int x[8],y[8],p[8];6 G" [ G) ~" c: m& o( C( n
if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;; S/ h7 ^, A$ R# J6 m
if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解
, G9 k' d8 ]9 y* D! i; U mm1=mm/2;* e) O8 M8 S: |3 ^; M/ K
if(mm%4<0)mm1--;) e8 |& q" e: P5 L
mm2=mm-mm1;( m( I$ Z( ]/ @2 x
nn1=nn/2;0 O+ C* y- r; m7 d; H& p3 \7 {
if(nn%4>0)nn1--; @) e4 O/ F' v+ F/ ?4 N8 W
nn2=nn-nn1;0 u* e$ l T- L4 b
//分割步0 K& P* x) \. z+ R7 K2 h( V
comp(mm1,nn1,offx,offy);
, D- R3 S# W( p comp(mm1,nn2,offx,offy+nn1);
3 u/ T: ^5 D$ G, v: r comp(mm2,nn1,offx+mm1,offy);
- }. b2 r* A! r }5 o comp(mm2,nn2,offx+mm1,offy+nn1);
* Q$ A( R( J0 g1 y //合并步
2 _/ [7 z, I0 J- e x[0]=offx+mm1-1;y[0]=offy+nn1-3;
e5 A9 T+ w) c; N, n% e3 L x[1]=x[0]-1;y[1]=y[0]+2;& [7 o f6 \6 L, G" c2 u
x[2]=x[1]-1;y[2]=y[1]+2;
, B4 x$ V" g; g' ?. W X x[3]=x[2]+2;y[3]=y[2]-1;$ ^ Y& l5 W1 y' F3 |3 x: ^5 ^
x[4]=x[3]+1;y[4]=y[3]+2;# y8 B/ T3 ]% q, ^$ l" N
x[5]=x[4]+1;y[5]=y[4]-2;
' ?8 D e8 ]# _; ~) K- z8 n: c x[6]=x[5]+1;y[6]=y[5]-2;
+ O' |# z8 I: B2 ^ x[7]=x[6]-2;y[7]=y[6]+1;
- R& j! t- }0 }
! o- n) e3 G$ J( @5 Y3 k for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);% P, z, E1 V8 Z# n8 k1 f, }0 l+ Y# O
for(i=1;i<8;i+=2){
1 e0 M% B2 T7 H4 u int j1=(i+1)%8,j2=(i+2)%8;* l* a& _7 h2 M* `
if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];
# ?. d4 R/ |' s" D( f M+ x' W else link[x[i]][y[i]].y=p[j1];
1 h3 I9 Z1 ^& i9 H" b1 K- f if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];
9 ]% |" s4 b1 x else link[x[j1]][y[j1]].y=p[i];
) I9 D8 ~ k3 o& A5 _) b }
7 W* f* o: t* V, t6 J return 0;9 s) G, ~; q( }7 |% Q4 B8 ^* ?% D ~9 h
}
; m6 \, Z% Y: E) ^; |4 j: |" {0 Q F" J' q# `: r- M, K: ?
- ` s) U3 L. e//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。; X' r/ S2 K- W0 H* E
0 l8 Q9 g0 W: Z0 R/ T: gvoid Knight::base(int mm,int nn,int offx,int offy)
' \+ q. a1 e# D" D{: R- M, c" i1 r+ K& C. W1 d
if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);- D* O& k1 \0 }
if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);. x4 [% m1 z; o5 `& c: o
if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);
; N, b; t3 a# g- d if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);2 g+ z0 r5 x1 U7 b+ A
if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);
5 h% I4 [% U% F) m" E% ` if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);2 b- ^% K. E. E4 |
if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);
; { D! I5 e# d- U, y& k if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);
1 z; X8 M/ J+ }/ ~3 F0 b0 e% M if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);% W$ E" I5 \. m5 D/ j' z( B7 Y/ G3 }$ B
}$ l( T$ ~" v5 u. K1 a1 ^
" c$ {+ w0 p6 R) w6 S) A/ @! r0 m0 S# R; q: T8 `
//其实质性的构造由算法build来完成。+ m# V- i2 w; \2 P4 E. D+ W. G
! g' W9 M7 v2 h4 y( \1 x4 D, {- d5 u
void Knight::build(int m,int n,int offx,int offy,int col,grid *b) u' L' `8 ~0 u
{( W2 x8 I4 k% L6 r/ m. h: N# ^' U
int i,p,q,k=m*n;( t% Q/ ]: W# W
for(i=0;i<k;i++){
* X1 ]. Y$ \7 L int x1=offx+b[i].x,# w/ s% O0 [% \1 Y+ p3 d+ y5 q0 s
y1=offy+b[i].y,
6 e) ^1 c, E: P3 ] x2=offx+b[(i+1)%k].x,3 o9 ?2 ^9 \, ~/ C6 E5 c
y2=offy+b[(i+1)%k].y;. k; q1 }8 M6 N+ y9 f Y5 `$ |& k
p=pos(x1,y1,col);q=pos(x2,y2,col);
" b$ v" Y- {9 ^4 z link[x1][y1].x=q;link[x2][y2].y=p;
0 L; b7 m( u! ]2 b } r* u7 M0 V0 S3 i; K
}
5 J2 h U9 D5 I7 k ]0 `
% @0 k9 e8 ^7 f3 V" @' T* f% E. k7 `6 f: e3 e: V8 C5 ]1 ]0 r
//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.
8 P% K/ ?" Q, H
5 x+ P. H% _' E9 q+ v: `int Knight::pos(int x,int y,int col)
! V4 H* U/ K& l; n: B$ n' n; d6 N{' ^% v1 P$ J6 p3 @4 ?, V) D$ r
return col*x|y;
" `- `" o' F$ C1 X. ~ p! L}
2 M4 u( g7 z" `" E% n( `
C D' p1 ~6 A6 d# {$ `8 [' Z( ?; P7 D; l& Z9 M* x. m
//最后,由out按照要求输出计算出的结构化Hamilton回路。6 M! B7 g. `' h+ E9 l
3 k8 a% ~% D" O# d& \9 t; G% |
void Knight: ut()
$ f e$ F! k5 I{+ i% V9 G; n0 c. |2 p2 q
int i,j,k,x,y,p,**a;- Y) o- ]" B+ M1 Z/ ]
Make2DArray(a,m,n);
, j% w5 U: b& e, E0 T" e if(comp(m,n,0,0)) return;
2 K$ ~$ G5 O4 N- V/ z) x for(i=0;i<m;i++)0 u& H s! Q/ }
for(j=0;j<n;j++) a[i][j]=0;
, |$ d3 \! Y( T1 ]! v( X$ @& c6 Q8 @ i=0;j=0;k=2;a[0][0]=1;$ @ {5 D2 L) E7 L/ N: u5 O- z
cout<<"(0,0)"<<"";8 R+ v4 V6 s; x
for(p=1;p<m*n;p++){& H: v: f0 O" ^6 T8 |: a
x=link[i][j].x;y=link[i][j].y;
% S1 I! B' }4 {, d0 S i=x/n;j=k%n;
1 k8 ?7 z" ^! W+ z s if(a[i][j]>0){i=y/n;j=y%n;}7 ^6 v' {+ h& _
a[i][j]=k++;+ f, o2 l; v$ |9 f) p: q6 B
cout<<"("<<i<<","<<j<<")";
! T5 n( E& Q! Q# P$ X1 Q$ j3 W if((k-1)%n==0) cout<<endl;
* ~" U7 s1 E6 i1 I+ i3 N' Y }( ~" L. [0 J: A7 l" v
cout<<endl;' K: N! }2 P. Z
for(i=0;i<m;i++){, x2 | u, d2 L# t: K* z7 [
for(j=0;j<n;j++) cout<<a[i][j]<<"";, f( `0 |: {4 G: z$ I
cout<<endl;9 q( x8 x8 u0 S
}
8 Y4 H+ r( s7 |} |
|