原题链接:http://poj.org/problem?id=2488
我的链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=19651#problem/A
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 23452 | Accepted: 7944 |
Description
Input
Output
Sample Input
3 1 1 2 3 4 3
Sample Output
Scenario #1: A1 Scenario #2: impossible Scenario #3: A1B3C1A2B4C2A3B1C3A4B2C4
Source
算法:DFS + 回溯
题意:骑士周游列国问题,说白了就是任一给你一个棋盘(当然满足格子数小于26)
让你从第一个格子按照图中所给的马走日的步法
不重复遍历走完整个棋盘。然后按照字典序输出路径即可
思路:按照图中的八个方向dfs即可。
注意: 1.回溯的用法,千万别忘了还原状态。
2.路径的输出,字典序的是列。。。
/****************************************************** //A Accepted 148 KB 0 ms C++ 1259 B 题意:骑士周游列国,马走日八个方向走,同时也要注意字典序 最后是按照字典序输出的 注意:先输入列再输入行 *******************************************************/ #include<stdio.h> #include<string.h> const int maxn = 30; int vis[maxn][maxn]; int n,m; int dir[8][2] = {-2,-1, -2,1, -1,-2, -1,2, 1,-2, 1,2, 2,-1, 2,1}; //注意方向也要按照字典序来 ,否则WA的好惨。。。 struct Path{ int x,y; }p[maxn]; int flag; void dfs(int x, int y, int step) { if(flag) return; p[step].x = x; p[step].y = y; if(step == n*m) { flag = 1; return; } Path next; for(int i = 0; i < 8; i++) { next.x = x+dir[i][0]; next.y = y+dir[i][1]; if(next.x >= 1 && next.x <= n && next.y >= 1 && next.y <= m && !vis[next.x][next.y]) { vis[next.x][next.y] = 1; dfs(next.x, next.y, step+1); vis[next.x][next.y] = 0; } } return; } int main() { int T; scanf("%d", &T); for(int t = 1; t <= T; t++) { scanf("%d%d", &m,&n); //先输入列再输入行 memset(vis,0,sizeof(vis)); memset(p,0,sizeof(p)); flag = 0; vis[1][1] = 1; dfs(1,1,1); printf("Scenario #%d:\n", t); if(flag) { for(int i = 1; i <= n*m; i++) printf("%c%d", p[i].x-1+'A', p[i].y); printf("\n"); } else printf("impossible\n"); if(t != T) printf("\n"); } return 0; }