Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge
在一个5 * 6的棋盘中的某个位置有一只马,如果它走29步正好经过除起点外的其他位置各一次,这样一种走法则称马的周游路线,试设计一个算法,从给定的起点出发,找出它的一条周游路线。
为了便于表示一个棋盘,我们按照从上到下,从左到右对棋盘的方格编号,如下所示:
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
25 26 27 28 29 30
马的走法是“日”字形路线,例如当马在位置15的时候,它可以到达2、4、7、11、19、23、26和28。但是规定马是不能跳出棋盘外的,例如从位置1只能到达9和14。输入有若干行。每行一个整数N(1<=N<=30),表示马的起点。最后一行用-1表示结束,不用处理。
对输入的每一个起点,求一条周游线路。对应地输出一行,有30个整数,从起点开始按顺序给出马每次经过的棋盘方格的编号。相邻的数字用一个空格分开。
4-1
注意:如果起点和输入给定的不同,重复多次经过同一方格或者有的方格没有被经过,都会被认为是错
误的
题目分析
深搜问题,要想加快搜索收敛,将现在可达的位置按照其下一步可达位置的数量排序,
先走可能性最少的路径,从而减少回溯的时间(参考1153,修改相应参数)
这里用普通的深搜也是可以做到的,不要用栈来存储路径,好像就是push和pop操作占了时间,
其实开一个30维的数组就够用了的
#include <stdio.h> #include <memory.h> #define ROW 5 #define COL 6 #define ALL 30 int path[ALL]; int count; int visited[ROW][COL]; int dir[8][2] = {{-2,-1},{-1,-2},{1,-2},{2,-1}, {2,1},{1,2},{-1,2},{-2,1}}; bool doit; void travel(int r, int c) { for (int i = 0; i < 8; ++i) { if (doit) return; int newr = r + dir[i][0]; int newc = c + dir[i][1]; if (newr >= 0 && newr < ROW && newc >= 0 && newc < COL && !visited[newr][newc]) { visited[newr][newc] = true; path[count++] = newr*COL + newc + 1; if (count == ALL) { doit = true; return; } travel(newr, newc); count--; visited[newr][newc] = false; } } } int main() { int num; while (scanf("%d", &num)) { if (num == -1) break; memset(visited, 0, sizeof(visited)); doit = false; count = 0; path[count++] = num; visited[(num-1)/6][(num-1)%6] = true; travel((num-1)/6, (num-1)%6); for (int i = 0; i < ALL; ++i) if (i == ALL-1) printf("%d\n", path[i]); else printf("%d ", path[i]); } }