马踏棋盘----深度搜索、回溯
马踏棋盘问题(又称骑士周游或骑士漫游问题)是算法设计的经典问题之一。
国际象棋的棋盘为8*8的方格棋盘,现将“马”放在任意指定的方格中,按照“马”走棋的规则将“马”进行移动。要求每个方格只能进入一次,最终使得“马”走遍棋盘64个方格。
编写代码,实现马踏棋盘的操作,要求用1~64来标注“马”移动的路径
对于在n*n的棋盘上,当n>=5且为偶数的时候,以任意点作点都有解。
回溯法:
思想很简单,就是一条路走到黑,碰壁了再回来一条路走到黑……一般和递归可以很好的搭配使用,还有深度优先搜索(DFS)。
实现代码
1 /*===========================================================================*\ 2 * 3 * 马踏棋盘问题 4 * 5 * 2013.06.01 by 樊列龙 6 * 7 * 源码来自鱼C工作室 8 \*===========================================================================*/ 9 10 #include <stdio.h> 11 #include <time.h> 12 13 #define X 8 14 #define Y 8 15 16 int chess[X][Y]; 17 18 //查找下一个位置 19 int nextxy(int* x, int* y, int count) 20 { 21 switch(count) 22 { 23 case 0: 24 if(*x + 2 <= X-1 && *y - 1 >= 0 && chess[*x+2][*y-1]==0) 25 { 26 *x += 2; 27 *y -= 1; 28 return 1; 29 } 30 break; 31 case 1: 32 if(*x + 2 <= X-1 && *y + 1 <= Y-1 && chess[*x+2][*y+1]==0) 33 { 34 *x += 2; 35 *y += 1; 36 return 1; 37 } 38 break; 39 case 2: 40 if(*x + 1 <= X-1 && *y - 2 >= 0 && chess[*x+1][*y-2]==0) 41 { 42 *x += 1; 43 *y -= 2; 44 return 1; 45 } 46 break; 47 case 3: 48 if(*x + 1 <= X-1 && *y + 2 <= Y - 1 && chess[*x+1][*y+2]==0) 49 { 50 *x += 1; 51 *y += 2; 52 return 1; 53 } 54 break; 55 case 4: 56 if(*x - 2 >= 0 && *y - 1 >= 0 && chess[*x-2][*y-1]==0) 57 { 58 *x -= 2; 59 *y -= 1; 60 return 1; 61 } 62 break; 63 case 5: 64 if(*x - 2 >= 0 && *y + 1 <= Y - 1 && chess[*x-2][*y+1]==0) 65 { 66 *x -= 2; 67 *y += 1; 68 return 1; 69 } 70 break; 71 case 6: 72 if(*x - 1 >= 0 && *y - 2 >= 0 && chess[*x-1][*y-2]==0) 73 { 74 *x -= 1; 75 *y -= 2; 76 return 1; 77 } 78 break; 79 case 7: 80 if(*x - 1 >= 0 && *y + 2 <= Y - 1 && chess[*x-1][*y+2]==0) 81 { 82 *x -= 1; 83 *y += 2; 84 return 1; 85 } 86 break; 87 88 default: 89 break; 90 } 91 92 return 0; 93 } 94 95 void print() 96 { 97 int i, j; 98 99 for(i = 0; i < X; i++) 100 { 101 for(j = 0; j < Y; j++) 102 { 103 printf("%2d\t", chess[i][j]); 104 } 105 printf("\n"); 106 } 107 108 printf("\n"); 109 } 110 111 int TravlChessBord(int x, int y, int tag) 112 { 113 int x1 = x, y1 = y, count = 0, flag = 0; 114 chess[x][y] = tag; 115 if(X*Y == tag) 116 { 117 print(); 118 return 1; 119 } 120 121 //找下一个位置 122 flag = nextxy(&x1,&y1,count); 123 while(flag == 0 && count < 7) 124 { 125 count++; 126 flag = nextxy(&x1,&y1,count); 127 } 128 129 while(flag) 130 { 131 printf("进入 <%d,%d>\n",x1,y1); 132 if(TravlChessBord(x1,y1,tag+1)) 133 { 134 return 1; 135 } 136 137 x1 = x; 138 y1 = y; 139 count++; 140 141 flag = nextxy(&x1,&y1,count); 142 while(flag == 0 && count < 7) 143 { 144 count++; 145 flag = nextxy(&x1,&y1,count); 146 } 147 } 148 149 if(0 == flag) 150 { 151 printf("退回... <%d,%d>)\n",x,y); 152 chess[x][y] = 0; 153 } 154 155 return 0; 156 } 157 158 int main() 159 { 160 int i, j; 161 clock_t start, finish; 162 163 start = clock(); 164 165 for(i = 0; i < X; i++) 166 { 167 for(j = 0; j < Y; j++) 168 { 169 chess[i][j] = 0; 170 } 171 } 172 173 174 if(!TravlChessBord(0,0,1)) 175 { 176 printf("抱歉马踏棋盘失败了!\n"); 177 } 178 else 179 { 180 print(); 181 } 182 183 finish = clock(); 184 185 186 printf("本次计算一共耗时 %f 秒\n\n",(double)(finish-start)/CLOCKS_PER_SEC); 187 188 return 0; 189 }
测试结果:
当棋盘大于5的时候耗费的时间比较长,因此这里取5 X 5 的棋盘做测试:
View Code1 进入 <2,1> 2 进入 <4,0> 3 进入 <3,2> 4 进入 <4,4> 5 进入 <2,3> 6 进入 <4,2> 7 进入 <3,0> 8 进入 <1,1> 9 进入 <0,3> 10 进入 <2,2> 11 进入 <4,1> 12 进入 <2,0> 13 进入 <0,1> 14 进入 <1,3> 15 进入 <3,4> 16 退回... <3,4>) 17 退回... <1,3>) 18 退回... <0,1>) 19 进入 <1,2> 20 进入 <3,1> 21 进入 <4,3> 22 进入 <2,4> 23 退回... <2,4>) 24 退回... <4,3>) 25 进入 <1,0> 26 进入 <0,2> 27 进入 <1,4> 28 进入 <3,3> 29 退回... <3,3>) 30 退回... <1,4>) 31 退回... <0,2>) 32 退回... <1,0>) 33 退回... <3,1>) 34 进入 <3,3> 35 进入 <1,4> 36 进入 <0,2> 37 进入 <1,0> 38 进入 <3,1> 39 进入 <4,3> 40 进入 <2,4> 41 退回... <2,4>) 42 退回... <4,3>) 43 退回... <3,1>) 44 退回... <1,0>) 45 退回... <0,2>) 46 退回... <1,4>) 47 退回... <3,3>) 48 进入 <2,4> 49 进入 <4,3> 50 进入 <3,1> 51 进入 <1,0> 52 进入 <0,2> 53 进入 <1,4> 54 进入 <3,3> 55 退回... <3,3>) 56 退回... <1,4>) 57 退回... <0,2>) 58 退回... <1,0>) 59 退回... <3,1>) 60 退回... <4,3>) 61 退回... <2,4>) 62 进入 <0,4> 63 退回... <0,4>) 64 退回... <1,2>) 65 退回... <2,0>) 66 进入 <3,3> 67 进入 <1,2> 68 进入 <3,1> 69 进入 <4,3> 70 进入 <2,4> 71 退回... <2,4>) 72 退回... <4,3>) 73 进入 <1,0> 74 进入 <0,2> 75 进入 <1,4> 76 退回... <1,4>) 77 退回... <0,2>) 78 退回... <1,0>) 79 退回... <3,1>) 80 进入 <2,0> 81 进入 <0,1> 82 进入 <1,3> 83 进入 <3,4> 84 退回... <3,4>) 85 退回... <1,3>) 86 退回... <0,1>) 87 退回... <2,0>) 88 进入 <2,4> 89 进入 <4,3> 90 进入 <3,1> 91 进入 <1,0> 92 进入 <0,2> 93 进入 <1,4> 94 退回... <1,4>) 95 退回... <0,2>) 96 退回... <1,0>) 97 退回... <3,1>) 98 退回... <4,3>) 99 退回... <2,4>) 100 进入 <0,4> 101 退回... <0,4>) 102 退回... <1,2>) 103 进入 <1,4> 104 进入 <0,2> 105 进入 <1,0> 106 进入 <3,1> 107 进入 <4,3> 108 进入 <2,4> 109 进入 <1,2> 110 进入 <2,0> 111 进入 <0,1> 112 进入 <1,3> 113 进入 <3,4> 114 退回... <3,4>) 115 退回... <1,3>) 116 退回... <0,1>) 117 退回... <2,0>) 118 进入 <0,4> 119 退回... <0,4>) 120 退回... <1,2>) 121 退回... <2,4>) 122 退回... <4,3>) 123 进入 <1,2> 124 进入 <2,0> 125 进入 <0,1> 126 进入 <1,3> 127 进入 <3,4> 128 退回... <3,4>) 129 退回... <1,3>) 130 退回... <0,1>) 131 退回... <2,0>) 132 进入 <2,4> 133 进入 <4,3> 134 退回... <4,3>) 135 退回... <2,4>) 136 进入 <0,4> 137 退回... <0,4>) 138 退回... <1,2>) 139 退回... <3,1>) 140 退回... <1,0>) 141 退回... <0,2>) 142 退回... <1,4>) 143 退回... <3,3>) 144 退回... <4,1>) 145 进入 <4,3> 146 进入 <2,4> 147 进入 <1,2> 148 进入 <3,1> 149 进入 <1,0> 150 进入 <0,2> 151 进入 <1,4> 152 进入 <3,3> 153 进入 <4,1> 154 进入 <2,0> 155 进入 <0,1> 156 进入 <1,3> 157 进入 <3,4> 158 退回... <3,4>) 159 退回... <1,3>) 160 退回... <0,1>) 161 退回... <2,0>) 162 退回... <4,1>) 163 退回... <3,3>) 164 退回... <1,4>) 165 退回... <0,2>) 166 退回... <1,0>) 167 退回... <3,1>) 168 进入 <3,3> 169 进入 <4,1> 170 进入 <2,0> 171 进入 <0,1> 172 进入 <1,3> 173 进入 <3,4> 174 退回... <3,4>) 175 退回... <1,3>) 176 退回... <0,1>) 177 退回... <2,0>) 178 退回... <4,1>) 179 进入 <1,4> 180 进入 <0,2> 181 进入 <1,0> 182 进入 <3,1> 183 退回... <3,1>) 184 退回... <1,0>) 185 退回... <0,2>) 186 退回... <1,4>) 187 退回... <3,3>) 188 进入 <2,0> 189 进入 <4,1> 190 进入 <3,3> 191 进入 <1,4> 192 进入 <0,2> 193 进入 <1,0> 194 进入 <3,1> 195 退回... <3,1>) 196 退回... <1,0>) 197 退回... <0,2>) 198 退回... <1,4>) 199 退回... <3,3>) 200 退回... <4,1>) 201 进入 <0,1> 202 进入 <1,3> 203 进入 <3,4> 204 退回... <3,4>) 205 退回... <1,3>) 206 退回... <0,1>) 207 退回... <2,0>) 208 进入 <0,4> 209 退回... <0,4>) 210 退回... <1,2>) 211 退回... <2,4>) 212 进入 <3,1> 213 进入 <1,0> 214 进入 <0,2> 215 进入 <1,4> 216 进入 <3,3> 217 进入 <4,1> 218 进入 <2,0> 219 进入 <0,1> 220 进入 <1,3> 221 进入 <3,4> 222 退回... <3,4>) 223 退回... <1,3>) 224 退回... <0,1>) 225 进入 <1,2> 226 进入 <2,4> 227 退回... <2,4>) 228 进入 <0,4> 229 退回... <0,4>) 230 退回... <1,2>) 231 退回... <2,0>) 232 退回... <4,1>) 233 进入 <1,2> 234 进入 <2,0> 235 进入 <4,1> 236 退回... <4,1>) 237 进入 <0,1> 238 进入 <1,3> 239 进入 <3,4> 240 退回... <3,4>) 241 退回... <1,3>) 242 退回... <0,1>) 243 退回... <2,0>) 244 进入 <2,4> 245 退回... <2,4>) 246 进入 <0,4> 247 退回... <0,4>) 248 退回... <1,2>) 249 退回... <3,3>) 250 退回... <1,4>) 251 退回... <0,2>) 252 退回... <1,0>) 253 进入 <1,2> 254 进入 <3,3> 255 进入 <4,1> 256 进入 <2,0> 257 进入 <0,1> 258 进入 <1,3> 259 进入 <3,4> 260 退回... <3,4>) 261 退回... <1,3>) 262 退回... <0,1>) 263 退回... <2,0>) 264 退回... <4,1>) 265 进入 <1,4> 266 进入 <0,2> 267 进入 <1,0> 268 退回... <1,0>) 269 退回... <0,2>) 270 退回... <1,4>) 271 退回... <3,3>) 272 进入 <2,0> 273 进入 <4,1> 274 进入 <3,3> 275 进入 <1,4> 276 进入 <0,2> 277 进入 <1,0> 278 退回... <1,0>) 279 退回... <0,2>) 280 退回... <1,4>) 281 退回... <3,3>) 282 退回... <4,1>) 283 进入 <0,1> 284 进入 <1,3> 285 进入 <3,4> 286 退回... <3,4>) 287 退回... <1,3>) 288 退回... <0,1>) 289 退回... <2,0>) 290 进入 <2,4> 291 退回... <2,4>) 292 进入 <0,4> 293 退回... <0,4>) 294 退回... <1,2>) 295 退回... <3,1>) 296 退回... <4,3>) 297 进入 <3,4> 298 进入 <1,3> 299 进入 <0,1> 300 进入 <2,0> 301 进入 <4,1> 302 进入 <3,3> 303 进入 <1,2> 304 进入 <3,1> 305 进入 <4,3> 306 进入 <2,4> 307 退回... <2,4>) 308 退回... <4,3>) 309 进入 <1,0> 310 进入 <0,2> 311 进入 <1,4> 312 退回... <1,4>) 313 退回... <0,2>) 314 退回... <1,0>) 315 退回... <3,1>) 316 进入 <2,4> 317 进入 <4,3> 318 进入 <3,1> 319 进入 <1,0> 320 进入 <0,2> 321 进入 <1,4> 322 退回... <1,4>) 323 退回... <0,2>) 324 退回... <1,0>) 325 退回... <3,1>) 326 退回... <4,3>) 327 退回... <2,4>) 328 进入 <0,4> 329 退回... <0,4>) 330 退回... <1,2>) 331 进入 <1,4> 332 进入 <0,2> 333 进入 <1,0> 334 进入 <3,1> 335 进入 <4,3> 336 进入 <2,4> 337 进入 <1,2> 338 进入 <0,4> 339 1 14 19 10 25 340 20 9 24 13 18 341 15 2 11 6 23 342 8 21 4 17 12 343 3 16 7 22 5 344 345 本次计算一共耗时 1.019000 秒