原本问题是9*10的中国象棋棋盘中至少需要多少匹马按规则走法才能遍历所有点(马有别脚的情况)?
问题类似n皇后问题,但比其更复杂,一开始我也想写一个暴力算法来先把结果得到,然而发现难度有点高,因为别马脚的情况导致问题太复杂,比如2*3的棋盘至少需要6匹马,3*3的棋盘至少需要9匹马:
马 马 马
马 马 马
马 马 马
于是我还是先考虑一匹马的情况。
先存一段在9*10的棋盘下只有一匹马从初始起点(0,0)按中国象棋规则的走法尽可能遍历棋盘的最优(目前应该是)走法代码(代码很渣,请轻喷~):
#include <stdio.h> #include <string.h> #define SIZE_X 10 #define SIZE_Y 9 void dfs(int map[][SIZE_Y], int s_x, int s_y) { if(map[s_x][s_y] != 1 && s_x > -1 && s_y > -1 && s_x < SIZE_X && s_y < SIZE_Y) { map[s_x][s_y] = 1; if(map[s_x + 2][s_y + 1] != 1 && s_x + 2 < SIZE_X && s_y + 1 < SIZE_Y) // 3 s_x += 2, s_y += 1; else if(map[s_x + 1][s_y + 2] != 1 && s_x + 1 < SIZE_X && s_y + 2 < SIZE_Y) // 1 s_x += 1, s_y += 2; else if(map[s_x - 1][s_y + 2] != 1 && s_x - 1 > -1 && s_y + 2 < SIZE_Y) // 2 s_x -= 1, s_y += 2; else if(map[s_x + 2][s_y - 1] != 1 && s_x + 2 < SIZE_X && s_y - 1 > -1) // 4 s_x += 2, s_y -= 1; else if(map[s_x - 2][s_y + 1] != 1 && s_x - 2 > -1 && s_y + 1 < SIZE_Y) // 5 s_x -= 2, s_y += 1; else if(map[s_x + 1][s_y - 2] != 1 && s_x + 1 < SIZE_X && s_y - 2 > -1) // 7 s_x += 1, s_y -= 2; else if(map[s_x - 2][s_y - 1] != 1 && s_x - 2 > -1 && s_y - 1 > -1) // 6 s_x -= 2, s_y -= 1; else if(map[s_x - 1][s_y - 2] != 1 && s_x - 1 > -1 && s_y - 2 > -1) // 8 s_x -= 1, s_y -= 2; printf("(%d %d)\n", s_x, s_y); dfs(map, s_x, s_y); } } int main() { int map[SIZE_X][SIZE_Y]; memset(map, 0, sizeof(map)); dfs(map, 0, 0); // initila starting point for(int i = 0; i < SIZE_X; i++) { for(int j = 0; j < SIZE_Y; j++) printf("%d ", map[i][j]); puts(""); } return 0; }
这里让我非常郁闷的是,这样的判断只合适初始起点在(0,0)位置上,还是我手动排列组合这几个判断,一组一组测试得到的,假如起点在左中位置,就要重新找到一组判断顺序...但我暂时没有好办法能解决这个问题 = =...总之目前这样的判断组合,最终只剩下20个点无法遍历...:
1 0 0 0 0 1 0 1 1
0 0 0 1 0 1 1 1 1
0 1 0 0 1 1 1 1 1
0 0 0 0 1 1 1 1 1
0 0 1 1 1 1 1 1 1
0 0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
走法:
(0,0) (2 1) (4 2) (6 3) (8 4) (9 6) (8 8) (6 7) (8 6) (9 8) (7 7) (5 8) (6 6) (8 7) (6 8) (7 6) (9 7) (7 8) (5 7) (3 8) (4 6) (6 5) (7 3) (9 4) (7 5) (5 6) (4 8) (2 7) (0 8) (1 6) (3 7) (1 8) (2 6) (4 7) (2 8) (3 6) (5 5) (7 4) (9 5) (8 3) (6 4) (8 5) (9 3) (7 2) (9 1) (7 0) (8 2) (9 0) (7 1) (9 2) (8 0) (6 1) (5 3) (4 5) (2 4) (4 3) (3 5) (5 4) (6 2) (8 1) (6 0) (5 2) (4 4) (2 5) (1 7) (0 5) (1 3) (3 4) (1 5) (0 7)
棋盘规格应该是通用的...还要解决的问题有:
1.判断顺序的组合影响到是否是最优走法
2.棋盘上增加马的数量,并加上别马脚的判断。