uva 10047 The Monocycle(优先队列优化bfs)

http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=116#problem/B

注意自行车到达同一个格子时,可以出于不同的状态。因为朝向不同,所以接触地面得扇形颜色可能不同。相当于把每个格子拆成四个点,表示为(x,y,d,col),d为朝向,col为接触地面的颜色。

容易出错的地方:

虽然说在每一个格子上要么直走,要么左转或右转。但从一个格子并不是发出三种状态,而是四种。因为从该格子出发也可以向后转,只不过走了两步。

优先队列优化。不能第一次到达’T‘并且是绿色就结束bfs。因为这次到达走的步数未必比后面到达走的步数小。

输出,题目说相邻两组之间输出空行,不是每一组后面都输出空行,被这个坑惨了。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stack>
#define LL long long
#define _LL __int64

using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 30;

int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
struct node
{
	int x,y;
	int d,col;
	int step;
	bool operator < (const struct node &tmp)const
	{
		return step > tmp.step;
	}
};

priority_queue <struct node> que;
char map[maxn][maxn];
int n,m;
int sx,sy;
int vis[maxn][maxn][4][5];
int ans;

bool bfs()
{
	memset(vis,0,sizeof(vis));
	while(!que.empty()) que.pop();

	vis[sx][sy][0][0] = 1;
	que.push((struct node){sx,sy,0,0,0});

	while(!que.empty())
	{
		struct node u = que.top();
		que.pop();
		if( map[u.x][u.y] == 'T' && u.col == 0)
		{
			ans = u.step;
			return true;
		}

		int x = u.x + dir[u.d][0];
		int y = u.y + dir[u.d][1];
		int col = (u.col+1)%5;

		if(x >= 1 && x <= n && y >= 1 && y <= m && map[x][y] != '#' && !vis[x][y][u.d][col])
		{
			vis[x][y][u.d][col] = 1;
			que.push((struct node){x,y,u.d,col,u.step+1});
		}

		int d1 = (u.d+1)%4;
		int d2 = (u.d+3)%4;
		int d3 = (u.d+2)%4;

		if(!vis[u.x][u.y][d1][u.col])
		{
			vis[u.x][u.y][d1][u.col] = 1;
			que.push((struct node){u.x,u.y,d1,u.col,u.step+1});
		}
		if(!vis[u.x][u.y][d2][u.col])
		{
			vis[u.x][u.y][d2][u.col] = 1;
			que.push((struct node){u.x,u.y,d2,u.col,u.step+1});
		}
		if(!vis[u.x][u.y][d3][u.col])
		{
			vis[u.x][u.y][d3][u.col] = 1;
			que.push((struct node){u.x,u.y,d3,u.col,u.step+2});
		}
	}
	return false;
}

int main()
{
	int item = 1;
	while(~scanf("%d %d",&n,&m))
	{
		if(n == 0 && m == 0) break;
		if(item != 1)
			printf("\n");
		printf("Case #%d\n",item++);
		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(bfs())
			printf("minimum time = %d sec\n",ans);
		else printf("destination not reachable\n");
	}
	return 0;
}



你可能感兴趣的:(优先队列,bfs)