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