POJ 3083 Children of the Candy Corn
2012-02-24 10:01
253 查看
这一题是比较麻烦的深搜加广搜的题,考察范围较广,题目大意是从起点出发分别找出左贴墙走、右贴墙与正常走到终点的最短路程。很自然联想到用广搜解决正常走的最短路径,用深搜解决另两种最短路程。难点是如何解决深搜时的方向问题,由于不会用C++提供的STL中德队列类,所以就自己写的,比较麻烦,不过思路应该还算清晰吧。
AC代码如下:
AC代码如下:
#include <iostream> #define MAX 100 #define MAXN 10000 using namespace std; char map[MAX][MAX]; int vis[MAX][MAX]; int dir1[4][2]={{0,-1},{1,0},{0,1},{-1,0}};//左优先,逆时针选择方向 int dir2[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//右优先,顺时针选择方向 int w, h; int d1, d2; struct queue{ int x, y, dis; }; struct queue que[MAXN]; struct queue s_pos;//用于记录S点的坐标 void ini() { int i, j; scanf("%d%d", &w, &h); for(i = 0; i < h; i++) for(j = 0; j < w; j++) { cin >> map[i][j]; if(map[i][j] == 'S')//记录S的坐标 { s_pos.x = i; s_pos.y = j; } } if(s_pos.x == 0)//因为由于S的位置不同第一步的方向也不同,所以要分情况讨论 { d1 = 1; d2 = 1;} else if(s_pos.x == h - 1) { d1 = 3; d2 = 3;} else if(s_pos.y == 0) { d1 = 2; d2 = 0;} else if(s_pos.y == w - 1) { d1 = 0; d2 = 2;} } int bfs(int si, int sj) { int di[4] = {1, 0, -1, 0}, dj[4] = {0, 1, 0, -1}; int front = 0, rear = 1, k, ti, tj; memset(vis, 0, sizeof(vis)); que[0].x = si; que[0].y = sj; que[0].dis = 1;//将S点的坐标放在队列中的第一位 vis[si][sj] = 1; while(front < rear) { if(map[que[front].x][que[front].y] == 'E') return que[front].dis+=2;//由于S跟E都要算一步,所以+2 for(k = 0; k < 4; k++)//枚举四个方向 { if(front == 0)//对刚开始时的方向进行讨论 { if(que[0].x == 0) { que[rear].x = si + 1; que[rear].y = sj;} else if(si == h - 1) { que[rear].x = si - 1; que[rear].y = sj;} else if(sj == 0) { que[rear].y = sj + 1; que[rear].x = si;} else if(sj == w - 1) { que[rear].y = sj - 1; que[rear].x = si;} vis[que[rear].x][que[rear].y] = 1; rear++; break; } else { ti = que[front].x + di[k]; tj = que[front].y + dj[k];//派生出的新坐标 if(!vis[ti][tj] && map[ti][tj] != '#') { vis[ti][tj] = 1; que[rear].x = ti; que[rear].y = tj;//将新坐标放入队尾 que[rear++].dis = que[front].dis + 1;//距离在前一点得基础上+1 } } } front ++; } } int dfs(int x, int y, int d, int dir[][2]) { int step, tmpx, tmpy, tmp; if (map[x][y] == 'E') return 1; for(int i = 0; i < 4; i++) { tmp = (d + i)%4; tmpx = x + dir[tmp][1];//派生出的新坐标 tmpy = y + dir[tmp][0]; if(tmpx >= 0&&tmpx < h && tmpy >= 0 && tmpy < w && map[tmpx][tmpy]!='#') break;//找到第一个可走的店 } step = dfs(tmpx, tmpy, (tmp + 3)%4, dir)+1;//递归找下一个点 return step; } int main() { int n; int min_line; int r_line, l_line; while(scanf("%d", &n)!= EOF) { while(n--) { ini(); min_line = bfs(s_pos.x, s_pos.y); l_line = dfs(s_pos.x, s_pos.y, d1, dir1); r_line = dfs(s_pos.x, s_pos.y, d2, dir2); printf("%d %d %d\n", l_line, r_line, min_line); } } return 0; }
相关文章推荐
- poj 3083 Children of the Candy Corn
- poj 3083 Children of the Candy Corn bfs
- poj 3083 -- Children of the Candy Corn
- Poj 3083 Children of the Candy Corn
- poj 3083--Children of the Candy Corn
- poj 3083 Children of the Candy Corn
- poj 3083 Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- Children of the Candy Corn--POJ 3083
- POJ 3083--Children of the Candy Corn
- Poj 3083 Children of the Candy Corn (DFS+BFS)
- POJ 3083 Children of the Candy Corn(BFS + DFS)
- POJ 3083 Children of the Candy Corn (DFS + BFS + 模拟)
- POJ 3083 Children of the Candy Corn (DFS+BFS)
- poj 3083 Children of the Candy Corn(dfs+bfs)
- POJ 3083 Children of the Candy Corn
- poj 3083 Children of the Candy Corn
- POJ 3083 Children of the Candy Corn
- poj 3083 Children of the Candy Corn
- 【POJ】3083- A Children of the Candy Corn DFS、BFS、迷宫靠墙走