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棋盘
设定每个方格的权重(权重越低越不容易到达):
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
//<< C++ How To Program >> Fifth Edition
{
{2, 3, 4, 4, 4, 4, 3, 2},
{3, 4, 6, 6, 6, 6, 4, 3},
{4, 6, 8, 8, 8, 8, 6, 4},
{4, 6, 8, 8, 8, 8, 6, 4},
{4, 6, 8, 8, 8, 8, 6, 4},
{4, 6, 8, 8, 8, 8, 6, 4},
{3, 4, 6, 6, 6, 6, 4, 3},
{2, 3, 4, 4, 4, 4, 3, 2}
}
每次取权重低的先走,依然是用回溯法。
对于N*N,每格权重算法:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
//[x][y] 方格的权重算法
int Weight(int x, int y)
{
int w = 0;
for(int i = 0; i < N; ++i)
{
if( canJump(x + move[i][0] ,y+move[i][1]) )
++w;
}
return w;
}
实现:再议了。
据说还有谈心算法什么的。有时间再看看,这题是做完了。
奇慢无比……