题意:走m*n迷宫,从S到T,'#'是墙,'.'可走,不能出界,走一步花费1s,站着转90度花费1s,要求走过的步数是5的倍数。一开始面朝北。求最少时间。
不同于一般的水题,把轮子的状态和方向、所在的位置 作为状态进行判重即可。
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson num<<1,le,mid
#define rson num<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
using namespace std;
//const int INF= ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn= 25+5 ;
//const int maxm= ;
int m,n;
char a[maxn][maxn];
int sy,sx,ey,ex;
int dir[3]={0,-1,+1};
int mov[4][2]={{-1,0},{0,+1},{+1,0},{0,-1} };// 0 1 2 3
struct Node
{
int y,x;
int dir,color;
int time;
Node(){}
Node(int y,int x,int dir,int color,int time):y(y),x(x),dir(dir),color(color),time(time){}
};
bool vis[maxn][maxn][4][5];
//green is 0 and north is 0
bool in(int &y,int &x)
{
return 1<=y&&y<=m&&1<=x&&x<=n;
}
int ans;
void check(Node a)
{
printf("y: %d x: %d dir: %d color: %d time :%d\n",a.y,a.x,a.dir,a.color,a.time);
}
void BFS()
{
ans=INF;
memset(vis,0,sizeof vis);
queue<Node>q;
q.push(Node(sy,sx,0,0,0) );
vis[sy][sx][0][0]=1;
while(!q.empty())
{
Node now=q.front();q.pop();
int y=now.y;
int x=now.x;
// cout<<endl;
// check(now);
for(int i=0;i<3;i++)
{
// cout<<i<<endl;
Node tmp=now;
tmp.dir=(tmp.dir+dir[i]+4)%4;
tmp.time+=1;
int f=tmp.dir;
int ty,tx;
if(!i)
{
tmp.color=(tmp.color+1)%5;
ty=tmp.y+mov[f][0];
tx=tmp.x+mov[f][1];
}
else
{
ty=y,tx=x;
}
if( !in(ty,tx) ||a[ty][tx]=='#' )
continue;
if(ty==ey&&tx==ex&&tmp.color==0) {ans=min(ans,tmp.time);return;}
if(vis[ty][tx][tmp.dir][tmp.color] )
continue;
vis[ty][tx][tmp.dir][tmp.color]=1;
tmp.y=ty;
tmp.x=tx;
q.push(tmp);
// check(tmp);
}
}
}
int main()
{
int kase=0;
while(~scanf("%d%d",&m,&n)&&(m||n))
{
if(kase++ ) putchar('\n');
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
scanf(" %c",&a[i][j]);
if(a[i][j]=='S')
sy=i,sx=j;
else if(a[i][j]=='T')
ey=i,ex=j;
}
}
// cout<<sy<<" "<<sx<<" "<<ey<<" "<<ex<<endl;
printf("Case #%d\n",kase);
BFS();
if(ans==INF) puts("destination not reachable");
else printf("minimum time = %d sec\n",ans);
}
return 0;
}