题目地址:http://poj.org/problem?id=3083
Sample Input
2 8 8 ######## #......# #.####.# #.####.# #.####.# #.####.# #...#..# #S#E#### 9 5 ######### #.#.#.#.# S.......E #.#.#.#.# #########
Sample Output
37 5 5 17 17 9
题目分析:T组数据,每组都会有一个起点S,一个终点E。 分别输出:左边优先搜索到E的步数 右边优先搜索到E的步数 最短步数到E
dfs搜索时候,控制好搜索下一个节点时的先后顺序。bfs找最短路最简单。
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <math.h> #include <iostream> #include <string> #include <queue> #include <stack> #include <vector> #include <algorithm> using namespace std; int n, m; char g[50][50]; struct node { int x,y; }S, E; bool ok(int x, int y) //判断是否出了边界 { if(x>=0 && x<n && y>=0 && y<m) return true; else return false; } //定义转向序列 int d[4][2]={ {0,-1},{-1,0},{0,1},{1,0} }; //定义0 1 2 3的运动位置 // 左 上 右 下 //上行0 右行1 下行2 左行3 int left_dfs(node S, int come, int path)//左优先dfs { node cur=S; int e; for(int i=0; i<4; i++){ e=(i+come)%4; int x=cur.x+d[e][0]; int y=cur.y+d[e][1]; if(!ok(x,y)) continue; if(x==E.x && y==E.y){ //printf("dao da le ----------- "); return path+1; } if(g[x][y]=='#') continue; if(x==cur.x && y!=cur.y) { if(y>cur.y) come=1; else come=3; } else if(x!=cur.x && y==cur.y) { if(x>cur.x)come=2; else come=0; } node cc; cc.x=x; cc.y=y; return left_dfs(cc, come, path+1); } } int d2[4][2]={ {0,1},{-1,0},{0,-1},{1,0} }; //定义0 1 2 3的运动位置 // 右 上 左 下 int right_dfs(node S, int come, int path) { node cur=S; int e; for(int i=0; i<4; i++){ e=(i+3+come)%4; int x=cur.x+d2[e][0]; int y=cur.y+d2[e][1]; //printf("x=%d y=%d ",x+1, y+1); if(!ok(x,y) ) continue; if(x==E.x && y==E.y){ //printf("*****"); return path+1; } if(g[x][y]=='#') continue; if(x==cur.x && y!=cur.y) {if(y>cur.y) come=0; else come=2; } else if(x!=cur.x && y==cur.y) {if(x>cur.x) come=3; else come=1; } node cc; cc.x=x; cc.y=y; //printf("come=%d x=%d y=%d ",come, x+1, y+1); return right_dfs(cc, come, path+1); } } int dir[4][2]={ {-1,0}, {1,0}, {0,-1}, {0,1} //定义 上下左右 }; int bfs_sp() { queue<node>q; int path[50][50]; memset(path, 0, sizeof(path)); bool vis[50][50]; memset(vis, false, sizeof(vis)); //标记节点是否走过 q.push(S);//将起点入队列 vis[S.x][S.y]=true;//标记访问 path[S.x][S.y]++; node cur; while(!q.empty()) { cur=q.front(); q.pop();//取出队首元素 //printf("%d--%d ", cur.x, cur.y); for(int i=0; i<4; i++){ int x=cur.x+dir[i][0]; int y=cur.y+dir[i][1]; if(ok(x, y) && (g[x][y]=='.'||g[x][y]=='E') && vis[x][y]==false ) { node cc; cc.x=x; cc.y=y; q.push(cc); path[x][y]=path[cur.x][cur.y]+1; vis[x][y]=true; if(g[x][y]=='E') { return path[x][y];} } } } } int main() { int tg; scanf("%d", &tg); int i, j; //输出左优先搜索+右优先搜索+最短路径 int ans1, ans2, ans3; while(tg--){ scanf("%d %d", &m, &n); //n行 m列 for(i=0; i<n; i++){ scanf("%s", g[i]); for(j=0; j<m; j++){ if(g[i][j]=='S'){ S.x=i; S.y=j; } //找到起点 else if(g[i][j]=='E') { E.x=i; E.y=j; } //找到终点 } } //建图完毕 //printf("s=%d %d ", S.x, S.y ); //printf("s=%d %d ", E.x, E.y ); //一开始S可以走的方向 int come; //标记运动方向 for(i=0; i<4; i++){ int x=S.x+d[i][0]; int y=S.y+d[i][1]; if(ok(x,y)&& g[x][y]!='#'){ if(i==0) come=3; //左 else if(i==1) come=0;//上 else if(i==2) come=1;//右 else come=2;//下 } } //printf("come=%d ", come ); ans1=left_dfs(S, come, 1); if(come==0) come=1; else if(come==1) come=0; else if(come==2) come=3; else if(come==3) come=2; //printf("come=%d ", come ); ans2=right_dfs(S, come, 1); ans3=bfs_sp(); printf("%d %d %d ", ans1, ans2, ans3); } return 0; }