中文题目,大家自己去读。
与一般的广搜题目不同的是,这个题目中有一个变数,那就是楼梯的方向,这个地方坑了我好久。
(主要原因是自己手贱,在判断判断楼梯方向与当前方向是否一致的时候,最后没有返回0)。
我的做法是,
如果下一个点是楼梯的话,判断方向与现在所走的方向是否一致,如果一致,那么直接经过楼梯;
如果不一致的话,那么就等待1s钟的时间,让楼梯的方向转过来,使得楼梯的方向与当前所行走的方向一致。具体实现见源代码:
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=25;
int map[maxn][maxn];
int dis[maxn][maxn];
struct node
{
int x,y;
}que[maxn*maxn*maxn];
int sx,sy,tx,ty;
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; //上下,左右
int n,m;
void init()
{
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
dis[i][j]=1000;
}
}
dis[sx][sy]=0;
return;
}
int ok(int d,int x,int t) //当前方向,当前桥的类型,当前时间。判断桥是否与当前方向一致
{
if((d==0 || d==1) && x==2 && t%2==0) return 1;
if((d==0 || d==1) && x==1 && t%2==1) return 1;
if((d==2 || d==3) && x==1 && t%2==0) return 1;
if((d==2 || d==3) && x==2 && t%2==1) return 1;
return 0; //就是这里坑了我好久。。。
}
void bfs()
{
int f=0,r=1;
init();
node now;
now.x=sx,now.y=sy;
que[f]=now;
while(f<r)
{
now=que[f++];
int x=now.x,y=now.y;
if(x==tx && y==ty)
{
printf("%d\n",dis[x][y]);
return;
}
node next;
for(int i=0;i<4;i++)
{
int xx=x+dir[i][0],yy=y+dir[i][1];
int t=0;
if(map[xx][yy]==-1) continue;
if(map[xx][yy]==1 || map[xx][yy]==2) //横着的桥用1表示,竖着的桥用数字2表示,墙壁是-1,空地是0
{
if(!ok(i,map[xx][yy],dis[x][y])) //暂时不能过桥,则停留1秒钟
t=1;
xx+=dir[i][0];
yy+=dir[i][1];
}
next.x=xx,next.y=yy;
if(dis[xx][yy]<=dis[x][y]+1+t) continue;
if(map[xx][yy]==0) //可以停留的地方
{
dis[xx][yy]=dis[x][y]+1+t;
que[r++]=next;
}
}
}
return;
}
int main()
{
// freopen("in.txt","r",stdin);
char ch[10];
while(scanf("%d%d",&n,&m)==2)
{
gets(ch);
memset(map,-1,sizeof(map));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
char c;
scanf("%c",&c);
if(c=='.' || c=='S' || c=='T') map[i][j]=0;
if(c=='-') map[i][j]=1;
if(c=='|') map[i][j]=2;
if(c=='S')
{
sx=i;
sy=j;
}
if(c=='T')
{
tx=i;
ty=j;
}
}
gets(ch);
}
bfs();
}
return 0;
}