诡异的楼梯
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Description
Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向.
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
Input
测试数据有多组,每组的表述如下:
第一行有两个数,M和N,接下来是一个M行N列的地图,’*’表示障碍物,’.’表示走廊,’|’或者’-‘表示一个楼梯,并且标明了它在一开始时所处的位置:’|’表示的楼梯在最开始是竖直方向,’-‘表示的楼梯在一开始是水平方向.地图中还有一个’S’是起点,’T’是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在’.’或’S’和’T’所标记的格子内.
Output
只有一行,包含一个数T,表示到达目标的最短时间.
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
Sample Input
5 5
**..T
*..
..|..
...
S….
Sample Output
7
Hint
Hint
地图如下:
思路:四个方向遍历过去,楼梯方向是跟行进方向一致时,直接行进,这里判断一下到达楼梯的时间的奇偶性就可以了,因为已经标明了它在一开始时所处的位置。
#include<bits/stdc++.h>
using namespace std;
const int Max = 25;
char mapn[Max][Max];
bool vis[Max][Max];
int ans;
int m,n;
int starti,startj;
int endi,endj;
int dis[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
struct PathRoad{
int x;
int y;
int cns;
};
bool isOut(int x,int y){
if(x < 0||y < 0||x >= m||y>=n){
return true;
}
if(vis[x][y]){
return true;
}
if(mapn[x][y]=='*'){
return true;
}
return false;
}
//判断是否需要等待变向
bool isexchange(PathRoad p, char q,int x){
p.cns++;
if(q == '|'){
if(x%2==0&&p.cns %2==0){
return true;
}
if(x%2==1&&p.cns%2==1){
return true;
}
return false;
}
if(q=='-'){
if(x%2==1&&p.cns%2==0){
return true;
}
if(x%2==0&&p.cns%2==1){
return true;
}
return false;
}
}
void bfs(){
memset(vis,false ,sizeof(vis));
queue<PathRoad> path;
PathRoad now,next;
now.x = starti , now.y = startj , now.cns = 0;
vis[now.x][now.y] = true;
path.push(now);
while(!path.empty()){
now = path.front();
path.pop();
//判断是否到达终点
if(now.x==endi&&now.y==endj){
ans = now.cns;
return;
}
//检索四个方向
for(int i = 0;i < 4;i++){
next.x = now.x+dis[i][0];
next.y = now.y+dis[i][1];
//判断是否越界
if(isOut(next.x,next.y)){
continue;
}
else if(mapn[next.x][next.y]=='.'){
next.cns = now.cns+1;
vis[next.x][next.y] = true;
path.push(next);
}
else{//如果是楼梯
if(isOut(next.x+dis[i][0],next.y+dis[i][1])) continue;
if(isexchange(now,mapn[next.x][next.y],i)){
next.x+=dis[i][0];
next.y+=dis[i][1];
vis[next.x][next.y] = true;
next.cns = now.cns+1;
path.push(next);
}
else{
next.x = now.x;
next.y = now.y;
next.cns = now.cns+1;
path.push(next);
}
}
}
}
}
int main(){
while(cin>>m>>n){
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
cin>>mapn[i][j];
if(mapn[i][j]=='S'){
mapn[i][j] = '.';
starti = i;
startj = j;
}
if(mapn[i][j]=='T'){
endi = i;
endj = j;
mapn[i][j] = '.';
}
}
}
bfs();
cout<<ans<<endl;
}return 0;
}
尴尬,写完之后发现蜜汁WA,debug用了一上午一直看搜索部分,感觉也没差啊。。直到我煞笔了一下看到了判断转向的函数。。手残把判断横向的时候的特判搞错了。。简直智障。。。