这题的关键之处:什么时候不能再重复访问某一格子?如何防止重复访问?
#include<stdio.h>
#include<string.h>
char ground[30][30];
//GREEN BLACK RED BLUE WHITE 0 1 2 3 4
//U R D L 0 1 2 3
struct cldir
{
int s[5][4];
cldir()
{
memset(s,0,sizeof(s));
}
void clear()
{
memset(s,0,sizeof(s));
}
};
struct st
{
int x,y,c,d,t;
st(int xx,int yy,int clr,int dir,int tim)
{
x=xx; y=yy;
c=clr; d=dir; t=tim;
}
st() {}
};
int m,n;
cldir vis[30][30]; //color,direction
st q[18000]; //position,color,direction,time
int bfs(int x,int y) //time increases by one each time
{
int front,rear;
front = rear =0;
q[rear++] = st(x,y,0,0,0);
vis[x][y].s[0][0] = 1;
st temp;
if(ground[x][y]=='T')
return 0;
while(front<rear)
{
temp = q[front++];
int nx,ny,nc,nd;
switch(temp.d)
{
case 0:
nx = temp.x-1;
ny = temp.y;
break;
case 1:
nx = temp.x;
ny = temp.y+1;
break;
case 2:
nx = temp.x+1;
ny = temp.y;
break;
case 3:
nx = temp.x;
ny = temp.y-1;
break;
}
nc = (temp.c+1)%5;
if(nx>=0&&nx<m&& ny>=0&&ny<n && ground[nx][ny]!='#'\
&& vis[nx][ny].s[nc][temp.d] ==0)
{
if(ground[nx][ny]=='T'&& nc == 0)
return temp.t+1;
q[rear++]=st(nx,ny,nc,temp.d,temp.t+1);
vis[nx][ny].s[nc][temp.d]=1;
}
nd =(temp.d+1)%4;
if(vis[temp.x][temp.y].s[temp.c][nd] ==0)
{
q[rear++]=st(temp.x,temp.y,temp.c,nd,temp.t+1);
vis[temp.x][temp.y].s[temp.c][nd] = 1;
}
nd=(temp.d-1+4)%4;
if(vis[temp.x][temp.y].s[temp.c][nd] ==0)
{
q[rear++]=st(temp.x,temp.y,temp.c,nd,temp.t+1);
vis[temp.x][temp.y].s[temp.c][nd] = 1;
}
}
return -1;
}
int main()
{
//
freopen("input.txt","r",stdin);
scanf("%d%d",&m,&n);
int numcase = 1;
while(true)
{
int si,sj;
int ei,ej;
for(int i = 0; i < m;i++)
{
scanf("%s", ground[i]);
char* p = strchr(ground[i],'S');
char* q = strchr(ground[i],'T');
if(p)
{
si = i;
sj = p-ground[i];
}
if(q)
{
ei = i;
ej = q-ground[i];
}
for(int j = 0; j < 30;j++)
{
vis[i][j].clear();
}
}
int min = bfs(si,sj);
printf("Case #%d\n",numcase++);
if(min==-1)
printf("destination not reachable\n");
else
printf("minimum time = %d sec\n",min);
scanf("%d%d",&m,&n);
if(!m && !n) break;
putchar('\n');
}
}