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