http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19491
题意:
给一个图,求s到T的最短时间
每一步可以转左转右,或者向前走一步
并且每走一步身体颜色变化一次,开始是绿色,朝北,共有5种颜色(循环变化)
要求到达T要是同一种颜色,
和一般bfs求最短路一样,只是多了两个因素
直接作为一个状态,那么一共有MN*5*4*3种情况,可接受【当然要vis掉走过的路】
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <set> #include <vector> #include <iostream> using namespace std; const double pi=acos(-1.0); double eps=0.000001; int min(int a,int b) {return a<b?a:b;} int max(int a,int b) {return a>b?a:b;} char tm[28][28]; struct node { int x,y; int dir ; int col ; int step; node(){} node(int a,int b,int c,int d ,int e) {x=a,y=b,dir=d,col=c;step=e;} }; int stx,sty; int edx,edy; int n,m; int vis[30][30][6][6]; queue <node> q; int dx[]={-1,0,1,0}; int dy[]={0,1,0,-1}; int main() { int cnt=1; while(cin>>n>>m ) { if (!n&&!m)break; memset(vis,0,sizeof vis); int i,j; for (i=1;i<=n;i++) scanf("%s",tm[i]+1); for (i=1;i<=n;i++) { for (j=1;j<=m;j++) { if (tm[i][j]=='S') {stx=i,sty=j; tm[i][j]='.';} if (tm[i][j]=='T') {edx=i,edy=j;} } } while(!q.empty()) q.pop(); node st(stx,sty,0,0,0); q.push(st); int flag=-1; while(!q.empty()) { node tp=q.front(); q.pop(); int x=tp.x; int y=tp.y; int c=tp.col; int d=tp.dir; if (x==edx&&y==edy&&c==0) { flag=tp.step; break; } if (!vis[x][y][c][(d+1)%4]) //turn { vis[x][y][c][(d+1)%4]=1; q.push(node(x,y,c,((d+1)%4),tp.step+1)); } if (!vis[x][y][c][(d-1+4)%4]) { vis[x][y][c][(d-1+4)%4]=1; q.push(node(x,y,c,(d-1+4)%4,tp.step+1)); } int i=d; int xx=x+dx[i]; int yy=y+dy[i]; if (!(xx>=1&&xx<=n&&yy>=1&&yy<=m)) continue; if (vis[xx][yy][(c+1)%5][d])continue; if (tm[xx][yy]=='#') continue; vis[xx][yy][(c+1)%5][d]=1; q.push(node(xx,yy,(c+1)%5,d,tp.step+1)); } if(cnt>1) puts(""); printf("Case #%d\n",cnt++); if (flag==-1) printf("destination not reachable\n"); else printf("minimum time = %d sec\n",flag); } return 0; }