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