poj2488 A Knight's Journey 之 dfs解法

来源:互联网 发布:石油进出口数据 编辑:程序博客网 时间:2024/06/07 02:11

题意:小马跳来跳去,要找到一条路能遍历所有格子,且字典序最小。


分析:

其一:显然从A1开始字典序最小,而每一步有八个方向可以选择,这几个方向要按字典序最小的顺序排序;

其二:采用深搜比较方便,考虑到不一定能一次搜索成功,因此需要进行棋盘还原。


解法一:采用数组记录坐标,即使搜索错了也可以直接更新。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef pair <char,int>P;int n,p,q;int visit[40][40];int x[8] = {-1, 1, -2, 2, -2, 2, -1, 1};int y[8] = {-2, -2, -1, -1, 1, 1, 2, 2};P path[1000];bool dfs(int a,int b,int step){path[step].first = b+'A';path[step].second = a+1;if(step+1 == p*q) return true;//全部走完for (int i = 0; i < 8; i += 1){int nx = a+x[i];int ny = b+y[i];if (nx >=0 && ny >= 0 && nx < p && ny < q && !visit[nx][ny] ) {visit[a][b] = 1;if(dfs(nx,ny,step+1)) return true;visit[a][b] = 0;//棋盘还原}}return false;}int main(){cin >> n;for (int i = 0; i < n; i += 1){cin >> p >> q;memset(visit,0,sizeof(visit));visit[0][0] = 1;if (dfs(0,0,0)){//输出printf("Scenario #%d:\n",i+1);for (int i = 0; i < p*q; i += 1){cout << path[i].first << path[i].second;}}else printf("Scenario #%d:\nimpossible",i+1);printf("\n\n");//注意格式}return 0;}
解法二:采用stack记录坐标,在可回溯条件下坐标入栈,入栈顺序是travel的反向结果。
#include <cstdio>#include <deque>#include <stack>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef pair <char,int>P;int n,p,q;int visit[40][40];int x[8] = {-1, 1, -2, 2, -2, 2, -1, 1};int y[8] = {-2, -2, -1, -1, 1, 1, 2, 2};stack <P> path;bool dfs(int a,int b,int step){if(step+1 == p*q) {path.push(make_pair(b+'A',a+1));return true;}//全部走完for (int i = 0; i < 8; i += 1){int nx = a+x[i];int ny = b+y[i];if (nx >=0 && ny >= 0 && nx < p && ny < q && !visit[nx][ny] ) {visit[a][b] = 1;if(dfs(nx,ny,step+1)) {//可成功回溯,这条路可以走path.push(make_pair(b+'A',a+1));return true;}visit[a][b] = 0;//棋盘还原}}return false;}int main(){cin >> n;for (int i = 0; i < n; i += 1){cin >> p >> q;memset(visit,0,sizeof(visit));visit[0][0] = 1;if (dfs(0,0,0)){//输出printf("Scenario #%d:\n",i+1);while (!path.empty()){P ans = path.top();path.pop();cout << ans.first << ans.second;}}else printf("Scenario #%d:\nimpossible",i+1);printf("\n\n");//注意格式}return 0;}


原创粉丝点击