骑士周游
Homework:
在n*n棋盘上,按国际象棋的走马规则,从棋盘的任何一个方格开始,让马走遍所有的方格,每个方格至少并且只准走过一次。设计求解算法。
利用回溯法,试探性的走,不行折返,再试探...
1 //骑士周游(qishizhouyou),with method of trace back
2 //Note:This program can list all probable ways , but costs a lot of time.
3 //Compiled in Code::Blocks on Ubuntu platform
4
5 //step[N*N] record the direction of each step
6 //move[8][2] eight probable directions
7 //chess[N][N] the order of points/grids
8 //pro in function trace(int ,int ,int) means pro steps jumped
9
11 #include <iostream>
12 #include <iomanip>
13 using namespace std;
14
15
16 const int N = 8;
17 int k = 0,i = 0;
18 int step[N*N];
19 int move[8][2] = {{2,1}, {1,2}, {-1,2}, {-2,1}, {-2,-1}, {-1,-2}, {1,-2}, {2,-1}}; //counter-clockwise direction
20 int chess[N][N];
21
22 void Init() //initialize
23 {
24 for(int i=0;i<N*N;++i)
25 {
26 step[i] = -1;
27 chess[i/8][i%8] = 0;
28 }
29 }
30
31
32 bool canJump(int x,int y)
33 {
34 if(x>=0 && x<N && y>=0 && y<N && chess[x][y]==0)
35 return true;
36 else
37 return false;
38 }
39
40 void Print()
41 {
42 for(int i=0;i<N;++i)
43 {
44 for(int j=0;j<N;++j)
45 cout<<setw(3)<<chess[i][j];
46 cout<<endl;
47 }
48 cout<<endl;
49 }
50
51
52 void trace(int pro,int x,int y)
53 {
54 if(pro>=N*N)
55 {
56 Print();
57 }
58 else
59 {
60 for(int i=0;i<8;++i)
61 {
62 if(canJump(x+move[i][0], y+move[i][1]))
63 {
64 x+=move[i][0];
65 y+=move[i][1];
66 chess[x][y]=pro+1;
67 step[pro]=i;
68 trace(pro+1,x,y);//after finish this step,try next step
69
70 chess[x][y]=0;//trace back
71 x-=move[i][0];
72 y-=move[i][1];
73 }
74 }
75 }
76 }
77
78
79
80 int main()
81 {
82 int x=0;
83 int y=0;
84 chess[x][y]=1;
85 trace(1,x,y);
86
87 return 0;
88 }
89
2 //Note:This program can list all probable ways , but costs a lot of time.
3 //Compiled in Code::Blocks on Ubuntu platform
4
5 //step[N*N] record the direction of each step
6 //move[8][2] eight probable directions
7 //chess[N][N] the order of points/grids
8 //pro in function trace(int ,int ,int) means pro steps jumped
9
11 #include <iostream>
12 #include <iomanip>
13 using namespace std;
14
15
16 const int N = 8;
17 int k = 0,i = 0;
18 int step[N*N];
19 int move[8][2] = {{2,1}, {1,2}, {-1,2}, {-2,1}, {-2,-1}, {-1,-2}, {1,-2}, {2,-1}}; //counter-clockwise direction
20 int chess[N][N];
21
22 void Init() //initialize
23 {
24 for(int i=0;i<N*N;++i)
25 {
26 step[i] = -1;
27 chess[i/8][i%8] = 0;
28 }
29 }
30
31
32 bool canJump(int x,int y)
33 {
34 if(x>=0 && x<N && y>=0 && y<N && chess[x][y]==0)
35 return true;
36 else
37 return false;
38 }
39
40 void Print()
41 {
42 for(int i=0;i<N;++i)
43 {
44 for(int j=0;j<N;++j)
45 cout<<setw(3)<<chess[i][j];
46 cout<<endl;
47 }
48 cout<<endl;
49 }
50
51
52 void trace(int pro,int x,int y)
53 {
54 if(pro>=N*N)
55 {
56 Print();
57 }
58 else
59 {
60 for(int i=0;i<8;++i)
61 {
62 if(canJump(x+move[i][0], y+move[i][1]))
63 {
64 x+=move[i][0];
65 y+=move[i][1];
66 chess[x][y]=pro+1;
67 step[pro]=i;
68 trace(pro+1,x,y);//after finish this step,try next step
69
70 chess[x][y]=0;//trace back
71 x-=move[i][0];
72 y-=move[i][1];
73 }
74 }
75 }
76 }
77
78
79
80 int main()
81 {
82 int x=0;
83 int y=0;
84 chess[x][y]=1;
85 trace(1,x,y);
86
87 return 0;
88 }
89
可试探出所有可能走法。时间复杂度,极大……O( 8n*n)
较优算法:
对于8*8棋盘
设定每个方格的权重(权重越低越不容易到达):
Code
每次取权重低的先走,依然是用回溯法。
对于N*N,每格权重算法:
Code
实现:再议了。
据说还有谈心算法什么的。有时间再看看,这题是做完了。
奇慢无比……