如果最后要求最短的时间,那么每一秒所在的状态为一个状态,这一秒可以引发的下一个状态再进入队列,每次取出队列的队首元素进行操作即可。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int maxn=30,maxm=18000;//18000=maxn*maxn*5*4
struct Point
{
int x,y,c,d;//c=color green=0,black=1,red=2,blue=3,white=4;
};
int dir[4][2]={{0,-1},{-1,0},{0,1},{1,0}};//west north east south
Point q[maxm];
bool grid[maxn][maxn],vis[maxn][maxn][5][4];
int dist[maxn][maxn][5][4];
int m,n;
bool is_equal(Point A,Point B)
{
if(A.x==B.x && A.y==B.y && A.c==B.c) return true;
return false;
}
int bfs(Point S,Point T)
{
vis[S.x][S.y][S.c][S.d]=true;
dist[S.x][S.y][S.c][S.d]=0;
int front=0,rear=0;
q[rear++]=S;
while(front<rear)
{
S=q[front++];
Point A;
for(int a=0;a<3;a++)
{
if(a==0)
{
A.x=S.x+dir[S.d][0];
A.y=S.y+dir[S.d][1];
A.c=(S.c+1)%5;
A.d=S.d;
}
else if(a==1 || a==2)
{
A.x=S.x;
A.y=S.y;
A.c=S.c;
if(a==1) A.d=(S.d+1)%4;
else A.d=(S.d-1+4)%4;
}
if(A.x>=0 && A.x<m && A.y>=0 && A.y<n &&
grid[A.x][A.y]==true && !vis[A.x][A.y][A.c][A.d])
{
vis[A.x][A.y][A.c][A.d]=true;
dist[A.x][A.y][A.c][A.d]=dist[S.x][S.y][S.c][S.d]+1;
q[rear++]=A;
if(is_equal(A,T)) return dist[A.x][A.y][A.c][A.d];
}
}
}
return 0;
}
int main()
{
#ifndef ONLINE_JUDGE
// freopen("10047.txt","r",stdin);
freopen("in.txt","r",stdin);
//freopen("myout.txt","w",stdout);
#endif
int N=0;
while(scanf("%d%d",&m,&n)==2 && m)
{
if(N) printf("\n");//注意这里不能再循环前设置Printf("\n");l
//因为题目说两个连续的实例之间才要换行
char s[maxn];
memset(grid,0,sizeof(grid));
memset(vis,0,sizeof(vis));
int i,j,k;
Point S,T;
for(i=0;i<m;i++)
{
scanf("%s",s);
for(j=0;j<n;j++)
if(s[j]!='#')
{
grid[i][j]=true;
if(s[j]=='S')
{
S.x=i;
S.y=j;
}
else if(s[j]=='T')
{
T.x=i;
T.y=j;
}
}
}
S.c=T.c=0;
S.d=1;
printf("Case #%d\n",++N);
int ans=bfs(S,T);
//printf("ans=%d\n",ans);
if(ans)
printf("minimum time = %d sec\n",ans);
else printf("destination not reachable\n");
}
return 0;
}