- 在线时间
- 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:3940376681 V" i: d; ]* {
! I9 V: _; l& {. y8 S; I. p- N* W
Hamilton周游路线问题
& K- f( h, B0 g; S7 U# }
" l4 Z( l8 M+ f4 M* b3 i* G8×8 的国际象棋棋盘上的一只马,恰好走过除起点外的其它63 个位置各一次,最后回到起点。这条路线称为一条马的Hamilton 周游路线。对于给定的m×n 的国际象棋棋盘,m和n均为大于5 的偶数,且|m-n|≤2,试设计一个分治算法找出一条马的Hamilton周游路线。
& c8 x5 {3 I2 {7 |7 R9 @5 H! q5 E2 _; j) M
对于给定的偶数m,n≥6,且|m-n|≤2,编程计算m×n 的国际象棋棋盘一条马的Hamilton周游路线。
2 ]! o( k6 a4 B9 ~, p2 x
; N5 _- g& R" N) c( d2 j' W! M0 J) A5 [2 R
* w) l/ ]5 N' W/ A//算法实现:
3 J* n/ C5 i; f+ v& Y
- G4 ~& |+ _: ~ X#include <iostream>
* j9 G) `! k9 n3 S- k6 d#include <fstream>
/ P2 b5 }% l- c) y3 i& P. ]) }3 O#include <stdlib.h>
+ L/ k( g# ~! w) g7 E#include <afxtempl.h> + N7 R0 X- K- m. @
using namespace std;
( R: ] w# P# ^9 U% {$ M0 i' rtemplate<class T>0 X5 O. y. N$ @, ]' K+ r
3 l' f* m w& @4 M* [3 _
void Make2DArray(T** &x , int rows , int cols ) * s( d u. H$ ?: b+ P& {/ [
{
/ B! m& ]0 n- [/ v- }3 } a //创建行指针 + L! Y) ^ Z+ U- @ E; q4 y
x = new T*[rows] ;
3 p9 H6 ^$ Y2 P% h' z8 T //为每一行分配空间
5 i% |4 ]3 U" T, l, P2 ^$ f+ A for( int i= 0 ; i<rows; i++ ) - }1 ^+ U4 B) K( h. s! ~1 G
{
7 l8 s" l+ b, I3 `5 o7 L x[i] = new int[cols] ;
; |2 X6 c( e' m# u: S; [/ T } ( e0 K. ^3 ], a
}
4 a( |) |, N- C( i2 }template<class T># B2 K5 y# X. w
$ s$ b) a* D4 O3 ~ R4 l7 G- Mvoid Delete2DArray(T** &x , int rows) , b* I; H* N$ B6 a
{
" i" ?9 G1 b$ r# T; P) T //释放为每一行所分配的空间
. [# n" h0 \! D% Q3 N' [; e for( int i = 0 ; i < rows ; i++ )
, L( D9 p# `- ]) R( q { * x& p5 [1 f- {2 m1 p+ C$ j
delete[] x[i] ; & Q/ E: R% D) F6 ~
}
- D9 N* P7 W$ c: } // 释放行指针
* h& m" z6 [; H# a$ \% A delete[] x ; 0 e& K) L( f5 U' ^3 [
x = 0 ;
8 a, b5 d- }" e' H( N$ E% C6 I& _$ I}& j8 \8 y% l8 ~0 U
$ Y3 s) |# \, p5 b9 s3 Y//其中,grid是表示整数对的结构。
8 D; p/ r) p/ [9 Z) C$ mtypedef struct; t q# Q8 B4 r( f2 J" l
{% O& Z. t# c; b6 j
int x;$ A: y& Q: f( ]8 m) G2 H
int y;
- F1 r. o T& g3 P) m4 Y}grid;
4 ^3 S' t; ^% H! F u' W
5 m: S6 s& v9 k, W1 \6 v//用一个类Knight实现算法。
' C$ C; a) r! ?- l+ E% t7 e. I& Y/ ]; e \6 L) u
- p) \0 b. {" Gclass Knight1 n+ }4 b- f8 `* v
{
+ v* U. f. ?5 A2 T a: apublic:
" i5 M& F, ^% @9 K* T ? Knight(int m,int n);
1 X2 P3 t3 z B; q/ S% ]) |% k! z ~Knight(){};+ @0 m- a/ g3 ?& P! y5 G
void out();
* N% C6 i" q* H6 l* Mprivate:
1 i) ?# O4 o* N6 x3 r6 Q' U int m,n;
/ F1 V5 Z! @6 c# t- U grid *b66,*b68,*b86,*b88,*b810,*b108,*b1010,*b1012,*b1210,**link;7 j( |/ o4 j& r' @: t; D
int pos(int x,int y,int col);/ |6 {+ C, u; C6 D
void step(int m,int n,int **a,grid *b);
+ s* O3 [5 S; W9 V9 ]: D void build(int m,int n,int offx,int offy,int col,grid *b);
5 [/ I* Z" ^9 D; n& n void base(int mm,int nn,int offx,int offy);7 f0 i. q% A& v5 l6 B4 U" @& l
bool comp(int mm,int nn,int offx,int offy );# `8 Y; P" u- V% i2 p
};
) Q, m5 \" x7 a7 r# O- o) I! [7 }4 Z. e2 o3 I a. _: P2 [
& e3 a5 r' p6 S5 ^
" w9 }% k2 {9 u9 h. Y! ?
4 T" H8 P/ ?) ~
//m和n分别表示棋盘的行数和列数。二维数组link用来表示Hamilton回路。
/ I9 W( D- y4 a1 x& w3 W/ R# |//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回路。
$ J! h3 z' P0 q7 v s8 F c2 G- ]4 d8 l4 A( ]0 d8 @( g
" G) M0 i& U: T0 Q
//构造函数读入基础数据,初始化各数组。
) O1 k: u5 g' V$ o: n# o# H& ^% @1 u6 i% v
Knight::Knight(int mm,int nn)
' n* o# T/ p8 _% V0 r: R! f. e{3 [2 T* w, I1 z7 R
int i,j,**a;/ t' [) [/ j/ C7 [ M
ifstream fin0;
, r% P7 S9 V! u9 C m=mm;n=nn;$ w/ V; [) c$ J2 b$ a; J+ S
b66=new grid[36];7 q) u+ o8 Y6 p9 G; l
b68=new grid[48];1 k3 A3 w6 e) W2 t0 j. y
b86=new grid[48];
. m: C/ M- f/ U b88=new grid[64];: `" z; k# c3 ~. U( u
b810=new grid[80];
) T- B$ _1 E8 _3 J b108=new grid[80];+ M5 N7 t. l8 [; @& M$ b6 [
b1010=new grid[100];; Y3 c Q* O I: F1 b4 O- d, a
b1012=new grid[120];
5 o- p% S3 a8 T, K. b b1210=new grid[120];
) l/ U9 F+ H' f" A6 ^- g. B& E Make2DArray(link,m,n);/ R% D/ w0 I" W% Q6 N2 }; M
Make2DArray(a,10,12);/ T" T) ^# E$ c# x+ B& u3 O9 |5 l r& _
- R; U3 q0 H2 [4 K for(i=0;i<6;i++)
' [% W8 c3 J; B for(j=0;j<6;j++) 2 e3 m/ d5 x0 c
fin0>>a[i][j];6 t* l! I; _$ z
step(6,6,a,b66);
4 h7 S" |9 x: G! K y for(i=0;i<6;i++)& s2 X% ]! p* a/ ^4 @
for(j=0;j<8;j++)
" c- g- v* F: [6 G; o. h: t fin0>>a[i][j];$ t# I- I; m4 J4 K- v% W- }
step(6,8,a,b68);
) h5 J0 a2 `0 p7 ^ \ step(8,6,a,b86);+ Z' c, C9 h; v, O* }& @
for(i=0;i<8;i++)
6 T" }, Q, o% M e K, l% Q for(j=0;j<8;j++)
) [+ C5 K7 S3 E! k fin0>>a[i][j];
4 H4 F7 ~2 h/ i+ j, | step(8,8,a,b88);
( r2 ] P) _8 ~* G6 \ for(i=0;i<8;i++)
- B$ }* E# q4 K& A0 Y, \( G for(j=0;j<10;j++)
8 f/ m& p$ Q! l: m( } fin0>>a[i][j];& G" i' I' s# M+ e
step(8,10,a,b810);7 r" z) B0 s& n/ [
step(10,8,a,b108);
" \7 M0 S O% R* ], w/ T! p2 L& b for(i=0;i<10;i++)! I( u# Q% y& G- p3 G
for(j=0;j<10;j++)
) J B: O% p/ h2 f/ d+ v fin0>>a[i][j];
& B2 ]3 H! \7 M& Z step(10,10,a,b1010);, D1 n. P- |4 m. Q& I' N1 k) m
for(i=0;i<10;i++)
. B3 h5 s) l5 X for(j=0;j<12;j++)
' J( }5 x1 d9 T. B fin0>>a[i][j];
4 {' ~/ \* M9 g6 \' D; I/ j step(10,12,a,b1012);
0 P+ A a1 `; t1 g, w$ u# W step(12,10,a,b1210);
4 f/ ~7 N5 }- Z2 H. H( \8 X; u
8 i# k9 t. o, F+ d}$ p9 G5 [6 w& P
7 C+ S. P2 n3 w6 {1 O5 a% r, C
/ h/ i) m6 K1 F- U: {! X
//其中,step用于将读入的基础棋盘的Hamilton回路转化为网格数据。. F& y d( H: O- c* A3 s3 e
6 w s% n: x3 x0 dvoid Knight::step(int m,int n,int **a,grid *b)( \, r5 A7 S! B7 |6 f
{
7 h0 \. ?* U3 r* t int i,j,k=m*n;: X# t# Y$ ?1 X9 P6 i
if(m<n)7 V" A7 X/ ]& X O# p+ t0 s5 U$ o
{
* _6 z# I% u* e6 E# |+ ^ for(i=0;i<m;i++). C, k: j3 i | \: {+ i" o
for(j=0;j<n;j++)" ]1 M' m3 R) e" B5 x
{: X+ U# O* t4 O' D
int p=a[i][j]-1;
5 a. d, Q2 W1 H8 s! n8 j b[p].x=i;b[p].y=j;
: a* m9 @# I2 o- ]; j1 n i$ B; ] }1 z3 D6 n% M* X; S" ^ f: K
}3 K9 q+ i8 {! A! @ e3 P
else{$ ~; I) _" E. ]$ i" e
for(i=0;i<m;i++)
* }0 V6 L+ d; ?, l for(j=0;j<n;j++){) A) z$ P a. n/ u0 n
int p=a[j][i]-1;/ C: e. ~' z: P9 @
b[p].x=i;b[p].y=j;
( t2 Z: S8 t" K% F" e }' `/ n+ L) ]- f3 S
}4 [+ L2 |0 K0 X0 t
}
) Z3 l+ p1 i: o( {& z
, [$ h% U* g! l$ U5 [; ]
+ G3 V! F) A8 \8 M+ X9 l//分治法的主体由如下算法comp给出。& @# u: }. v0 R2 p+ Y" F% H
bool odd(int data)
0 ~8 T) [- Q; @$ A$ X{5 U8 }" P+ G$ d; y6 K
if (data%2 ==0)
/ [* z" c" h8 t) p2 r$ P0 M: a {
5 f& D. m" Q% k6 T% l7 e! _) F return false;0 Q3 _% A# B1 L9 L1 j& l l
}" v" E. U" J Y5 K _# R0 a
return true;5 C2 g5 `4 c- ]
}
" }# G8 t; L! L
" d/ L3 ^4 |* Q R) {; l$ Y2 t) A) s/ z- Q7 A/ d: L
bool Knight::comp(int mm,int nn,int offx,int offy)* H9 _; p8 g0 J0 [; C- Z
{" @8 v* E9 ^) k; X" f
int mm1,mm2,nn1,nn2;& o# p, o2 n) O' O% m: k
int x[8],y[8],p[8];
" Y2 ?+ s9 ?! ]# M- t" ]$ ^ if(odd(mm)||odd(nn)||mm-nn>2||nn-mm>2||mm<6||nn<6)return 1;2 Z7 E' W* T2 U% \- s s8 k
if(mm<12||nn<12){base(mm,nn,offx,offy);return 0;} //基础解
4 P i6 f, e. N: S" n mm1=mm/2;4 s$ p. B, e/ E! a6 l/ C% b; {
if(mm%4<0)mm1--;
8 @: R3 b+ e- S; |, L) Y mm2=mm-mm1;* ]& y& B' `- h! Y* m6 M4 {: \
nn1=nn/2;
H2 d& F- V C" v1 U, N if(nn%4>0)nn1--;
* M- ^* G4 I a# E n+ j- K nn2=nn-nn1;. W- w5 t- Q- q8 [
//分割步
. [% S& c7 v4 s& P; A comp(mm1,nn1,offx,offy);( E+ T% h3 K! t# z# P
comp(mm1,nn2,offx,offy+nn1);
. |, Y% E! u. P comp(mm2,nn1,offx+mm1,offy);
. K& j7 m2 c* n8 r comp(mm2,nn2,offx+mm1,offy+nn1);
" l+ o: x' |/ |+ \. y4 h //合并步
8 L% ]: u+ q W+ ^% O- ]& P% h" B x[0]=offx+mm1-1;y[0]=offy+nn1-3;
0 M( e8 y& |0 A6 i4 k0 Y& g x[1]=x[0]-1;y[1]=y[0]+2;
, w% ?* {7 g1 w. C& M$ D" H x[2]=x[1]-1;y[2]=y[1]+2;
1 Q( {; H. B8 V5 m3 E, f x[3]=x[2]+2;y[3]=y[2]-1;% L& I) z v2 [% F% [9 g
x[4]=x[3]+1;y[4]=y[3]+2;
5 X/ X& }' d L X x[5]=x[4]+1;y[5]=y[4]-2;
9 P0 z- k8 w, I+ G4 E: Y+ g1 d x[6]=x[5]+1;y[6]=y[5]-2;4 _* v) f" l: z
x[7]=x[6]-2;y[7]=y[6]+1;
- e1 J( w0 \% q$ b # P- K7 |- v4 c! o4 {6 B) x2 n
for(int i=0;i<8;i++) p[i]=pos(x[i],y[i],n);8 t' z2 S' R v, ^5 V/ \
for(i=1;i<8;i+=2){9 B& d- ]9 S# D
int j1=(i+1)%8,j2=(i+2)%8;( T: U2 T7 H% c j! L8 Q; F* Q1 K
if(link[x[i]][y[i]].x==p[i-1]) link[x[i]][y[i]].x=p[j1];% Z5 F) f+ w: D
else link[x[i]][y[i]].y=p[j1];8 v0 M! e% A w& A$ m6 R2 i
if(link[x[j1]][y[j1]].x==p[j2]) link[x[j1]][y[j1]].x=p[i];3 |' W- |3 N) D9 e
else link[x[j1]][y[j1]].y=p[i];
+ n6 {4 d t, A# R2 O) b4 \1 S- A" y }1 P6 P: _. _& O5 o
return 0;" H5 P t+ r# m. o
}9 v8 w d$ }& G5 ]
! b6 K3 x* F8 [+ z) _' ? H% h
/ _, \; ^* n# F3 r8 o8 m, A+ y9 e* F' V) P//其中,base是根据基础解构造子棋盘的结构化Hamilton回路。
) g/ G% @5 {6 I) a# w8 q9 L# ~, Q" B2 E Q# h
void Knight::base(int mm,int nn,int offx,int offy)" ?. J) {! |5 X* Z6 g4 ]
{
. C3 c' `% Q4 f4 A2 I; m if(mm==6&&nn==6)build(mm,nn,offx,offy,n,b66);
; T y3 X* ~4 p% g6 U1 k if(mm==6&&nn==8)build(mm,nn,offx,offy,n,b68);
$ ]7 w5 i! e1 E$ p" x6 ] if(mm==8&&nn==6)build(mm,nn,offx,offy,n,b86);. M! _) @: g$ J
if(mm==8&&nn==8)build(mm,nn,offx,offy,n,b88);
' w6 [$ @4 D" l8 e- }$ \, a if(mm==8&&nn==10)build(mm,nn,offx,offy,n,b810);
% l, |- q6 L9 L6 z( y if(mm==10&&nn==8)build(mm,nn,offx,offy,n,b108);( V, X1 j6 W; o' O9 s: W
if(mm==10&&nn==10)build(mm,nn,offx,offy,n,b1010);4 y# k9 Q: K# {/ z. e
if(mm==10&&nn==12)build(mm,nn,offx,offy,n,b1012);, {1 q/ _; V( I) f
if(mm==12&&nn==10)build(mm,nn,offx,offy,n,b1210);! J: P4 Q' W( x! P* i& I- K
}" ]6 Y8 b$ @7 x% s/ U" @4 r! |
) X2 E" }4 V. t; w2 z, `* C4 u
5 n/ r+ @8 [/ I6 e! _" O. _2 o
//其实质性的构造由算法build来完成。
. V" S- L) D0 K2 G' Y% X
/ F4 p2 z0 y- uvoid Knight::build(int m,int n,int offx,int offy,int col,grid *b)$ y( n2 n5 {1 i
{! x* P+ g: ^8 h/ v" {
int i,p,q,k=m*n;
: @5 j0 F |( v4 ~3 R, A for(i=0;i<k;i++){
, z" s" O8 A5 v- T( K int x1=offx+b[i].x,
8 c) l/ |/ U$ P6 |1 @$ Y6 d- }6 V y1=offy+b[i].y,
4 F% m) v& a8 H5 Z x2=offx+b[(i+1)%k].x,6 I. ?4 L5 C( u, } A
y2=offy+b[(i+1)%k].y;
4 Y6 i) i( p$ \" t+ d2 V, D" A0 | p=pos(x1,y1,col);q=pos(x2,y2,col);/ u1 O8 R4 @5 d% P5 \5 P. W4 F
link[x1][y1].x=q;link[x2][y2].y=p;
3 ]$ l8 f+ T5 m9 d% C) a# ` } . F% ]) W% d+ ?5 }2 y
}) ]4 A' {$ @6 s" m7 K# M9 B4 q' d
4 s! j7 n% f6 B1 s: |
; E0 C0 T5 b$ V+ u4 M" ~//其中,pos用于计算棋盘方格的编号。棋盘方格各行从上到下,各列从左到右依次编号为0,1,....,mn-1.
9 i( L5 b' X& i" K9 `
2 i7 u! b* [% Y% c2 O9 pint Knight::pos(int x,int y,int col)
% i" p: U& [: e) C. l. x: `' `{) h5 ` d* ]9 ]0 Y' ~. H. m
return col*x|y;* B7 N7 E4 Y* a, _, m. \" \. H
}0 p' [4 g7 I" }: t0 M7 ^7 c' Y" a |
* g8 J( t" h: i7 P2 ?
9 J5 |' r) } Q9 ~9 ?//最后,由out按照要求输出计算出的结构化Hamilton回路。
( z7 {( Q9 H/ i2 x4 P7 k! w" ~1 J9 F ^. |8 d
void Knight: ut()
( F, K( M( R, H' q' J" U% `{6 a$ {/ A; a, ~0 N
int i,j,k,x,y,p,**a;3 R' v3 X1 `$ `* y5 e( A$ f( f( o
Make2DArray(a,m,n);9 p$ |9 Z% y, J3 {7 A
if(comp(m,n,0,0)) return;
& S; q2 @6 `9 ]% h& q" h K' \ for(i=0;i<m;i++)
' Q7 e/ ~. f1 Y g( O for(j=0;j<n;j++) a[i][j]=0;
+ p. [+ q4 V* p2 z i=0;j=0;k=2;a[0][0]=1;! e) I: m M% T- F0 j
cout<<"(0,0)"<<"";
' m/ w1 C7 I: i for(p=1;p<m*n;p++){! `9 T# D, {% |4 a! N$ t
x=link[i][j].x;y=link[i][j].y;, I: s& M) a( b& [; \4 w. K; T6 H
i=x/n;j=k%n;
) a$ j$ W6 Z H5 _ if(a[i][j]>0){i=y/n;j=y%n;}
% ^4 w, w+ G/ ^9 A a[i][j]=k++;
/ c8 ]5 r2 \% J& M; }3 { cout<<"("<<i<<","<<j<<")";
, ?3 N5 k+ D u6 g `2 | if((k-1)%n==0) cout<<endl;7 W& ^( B9 U L: O
}
- H; a, H y$ M2 }; G( X cout<<endl;- L6 ~1 a- A3 L* J& m5 V
for(i=0;i<m;i++){, A" t1 Z2 h d6 B) f( s X, J
for(j=0;j<n;j++) cout<<a[i][j]<<"";" I( M0 v/ d" W( V) ^
cout<<endl;' o8 V/ Z3 G+ @+ ]& F
}
$ |% _) M# H" s) O8 t5 ~, G} |
|