UVA 10047 - The Monocycle BFS

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;
}




你可能感兴趣的:(编程,ACM,uva,bfs)