UVA 10047 - The Monocycle BFS

时间:2024-07-10 14:36:44

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=988

题目大意:

独轮车的车轮被分为5个扇形,分别涂上一种不同的颜色,现在有一个人行驶在M*N的玩个平面上。每个格子的大小刚好为一个扇形。有些格子有障碍,骑车的人从S出发要到达T,途中,在任何一个格子的时候他要么骑到下一个格子,要么左转或者右转90度,初始他面朝北,并且绿色格子贴着地面,要求到终点时候也是绿色格子贴着地面。



思路:

半年前觉得挺难的题目现在看起来好简单。哈哈哈哈哈哈哈哈哈~

BFS。。

状态需要记录方向和此时的颜色。

代码略丑。主要是BFS过程中我是直接枚举的。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN=30;
char map[MAXN][MAXN];
bool vis[MAXN][MAXN][5][4];//x,y,color,dir
int m,n;
struct state
{
int x,y;
int step;
int dir;//direction :north:0 south:1 east:2 west:3
int color;//开始为0,终点也要为0
bool operator <(const state &a)const {
return step > a.step;
}
state(){;}
state(int x,int y,int step,int dir,int color) :x(x) ,y(y),step(step), dir(dir), color(color){}
}start,fin;
int bfs()
{
memset(vis,0,sizeof(vis));
priority_queue<state> q;
q.push(start);
vis[start.x][start.y][start.color][start.dir]=true;
while(!q.empty())
{
state cur=q.top();
q.pop();
if(cur.x==fin.x && cur.y==fin.y && cur.color==0)//找到答案了!
return cur.step; int x=cur.x,y=cur.y,step=cur.step,color=cur.color,dir=cur.dir;
switch(cur.dir)
{
case 0: //北
if(!vis[x-1][y][(color+1) % 5][dir] && map[x-1][y]!='#')
{
vis[x-1][y][(color+1) % 5][dir]=1;
q.push(state(x-1,y,step+1,dir,(color+1) % 5));
}
if(!vis[x][y][color][2]){
vis[x][y][color][2]=1; q.push(state(x,y,step+1,2,color));
}
if(!vis[x][y][color][3]) {
vis[x][y][color][3]=1; q.push(state(x,y,step+1,3,color));
}
break;
case 1: //南
if(!vis[x+1][y][(color+1) % 5][dir] && map[x+1][y]!='#')
{
vis[x+1][y][(color+1) % 5][dir]=1;
q.push(state(x+1,y,step+1,dir,(color+1) % 5));
}
if(!vis[x][y][color][2]){
vis[x][y][color][2]=1; q.push(state(x,y,step+1,2,color));
}
if(!vis[x][y][color][3]) {
vis[x][y][color][3]=1; q.push(state(x,y,step+1,3,color));
}
break;
case 2: //东
if(!vis[x][y+1][(color+1) % 5][dir] && map[x][y+1]!='#')
{
vis[x][y+1][(color+1) % 5][dir] =1;
q.push(state(x,y+1,step+1,dir,(color+1) % 5));
}
if(!vis[x][y][color][0]){
vis[x][y][color][0]=1; q.push(state(x,y,step+1,0,color));
}
if(!vis[x][y][color][1]){
vis[x][y][color][1]=1; q.push(state(x,y,step+1,1,color));
}
break;
case 3: //西
if(!vis[x][y-1][(color+1) % 5][dir] && map[x][y-1]!='#')
{
vis[x][y-1][(color+1) % 5][dir]=1;
q.push(state(x,y-1,step+1,dir,(color+1) % 5));
}
if(!vis[x][y][color][0]){
vis[x][y][color][0]=1; q.push(state(x,y,step+1,0,color));
}
if(!vis[x][y][color][1]){
vis[x][y][color][1]=1; q.push(state(x,y,step+1,1,color));
}
break;
}
}
return -1;
}
int main()
{
int kase=1;
while(~scanf("%d%d",&m,&n),m||n)
{
for(int i=1;i<=m;i++)
scanf("%s",map[i]+1);
for(int i=0;i<=n+1;i++) //最外面加上一层围墙,等下过程就可以减少判断。
map[0][i]=map[m+1][i]='#';
for(int i=0;i<=m+1;i++)
map[i][0]=map[i][n+1]='#';
/*
for(int i=0;i<=m+1;i++)
{
for(int j=0;j<=n+1;j++)
printf("%c",map[i][j]);
puts("");
}
*/
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(map[i][j]=='S')
{
state temp(i,j,0,0,0);
start=temp;
map[i][j]='.';
}
else if(map[i][j]=='T')
{
state temp(i,j,0,0,0);
fin=temp;
map[i][j]='.';
}
}
}
int ans=bfs();
if(kase!=1)
printf("\n");
printf("Case #%d\n",kase++);
if(ans==-1)
printf("destination not reachable\n");
else
printf("minimum time = %d sec\n",ans);
}
return 0;
}