http://poj.org/problem?id=3083
题意:有一个W*H的map,‘#’表示障碍,‘.‘表示空地,‘S‘表示起点,‘E‘表示终点,且保证起点与终点各有一个。
分别输出左转优先,右转优先以及最短的S到E的步数。。
思路:显然左转优先与右转优先dfs,最短路径bfs。
我定义的方向是 上右下左 分别为 0 1 2 3.
那么左转可表示为 d = (d+3)%4,右转可表示为 d = (d+1)%4.
左转优先时先右转,然后顺时针dfs;右转优先时先左转然后逆时针dfs。
最后,右转优先从S到E相当于左转优先从E到S,所以右转是可以转化为左转,一个dfs即可。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
int dir[4][2] = { {-1,0},{0,1},{1,0},{0,-1} }; // 0 1 2 3 对应 上右下左
struct node
{
int x,y;
int step;
};
int n,m;
char map[50][50];
queue <struct node> que;
int dfs(int x, int y,int ex, int ey,int d, int step)
{
if(x == ex && y == ey)
return step;
d = (d+3)%4; //优先左转
int xx = x+dir[d][0];
int yy = y+dir[d][1];
while( map[xx][yy] == ‘#‘) //顺时针旋转直到可以走为止
{
d = (d+1)%4;
xx = x+dir[d][0];
yy = y+dir[d][1];
}
return dfs(xx,yy,ex,ey,d,step+1);
}
int bfs(int sx,int sy,int ex,int ey)
{
int vis[50][50];
memset(vis,0,sizeof(vis));
while(!que.empty()) que.pop();
vis[sx][sy] = 1;
que.push( (struct node) {sx,sy,1});
while(!que.empty())
{
struct node u = que.front();
que.pop();
if(u.x == ex && u.y == ey)
return u.step;
for(int d = 0; d < 4; d++)
{
int x = u.x+dir[d][0];
int y = u.y+dir[d][1];
if(map[x][y] != ‘#‘ && !vis[x][y])
{
vis[x][y] = 1;
que.push( (struct node) {x,y,u.step+1});
}
}
}
}
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
int sx,sy,ex,ey;
scanf("%d %d",&m,&n);
memset(map,‘#‘,sizeof(map));
for(int i = 1; i <= n; i++)
{
scanf("%s",map[i]+1);
for(int j = 1; j <= m; j++)
{
if(map[i][j] == ‘S‘)
{
sx = i;
sy = j;
}
if(map[i][j] == ‘E‘)
{
ex = i;
ey = j;
}
}
}
printf("%d %d %d\n",dfs(sx,sy,ex,ey,0,1), dfs(ex,ey,sx,sy,0,1), bfs(sx,sy,ex,ey));
}
return 0;
}
poj 3083 Children of the Candy Corn(dfs+bfs),布布扣,bubuko.com
poj 3083 Children of the Candy Corn(dfs+bfs)
原文:http://blog.csdn.net/u013081425/article/details/22094189