hdu1180 诡异的楼梯 bfs

题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1180/

题目和不同的bfs有个不同的地方就是存在横着的或者竖着的楼梯,楼梯每过一个时刻就改变一次横竖的走向,人可以通过楼梯到达楼梯另一端的位置而只花费1的时间。所以我们只要在遇到楼梯的位置查看楼梯当前的走向,判断和人的横竖方向是否相同就行,相同则花费1时间,不同则花费2时间。

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int ui;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 #define pf printf
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 #define prime1 1e9+7
 9 #define prime2 1e9+9
10 #define pi 3.14159265
11 #define lson l,mid,rt<<1
12 #define rson mid+1,r,rt<<1|1
13 #define scand(x) scanf("%llf",&x) 
14 #define f(i,a,b) for(int i=a;i<=b;i++)
15 #define scan(a) scanf("%d",&a)
16 #define dbg(args) cout<<#args<<":"<<args<<endl;
17 #define inf 0x3f3f3f3f
18 #define maxn 25
19 int n,m,t;
20 int sx,sy,tx,ty;
21 int dir[][2]={1,0,-1,0,0,1,0,-1};//横向与纵向 
22 bool vis[maxn][maxn];
23 char Map[maxn][maxn];
24 struct node{
25     int x,y,step;
26     node(int x,int y,int s):x(x),y(y),step(s){}
27     node(){}
28     friend bool operator < (node a,node b)
29     {
30         return a.step>b.step;//由于优先队列是以最大为顶,所以就反向定义操作符使得最小step为顶 
31     }
32 };
33 node cur,nxt;
34 bool ok(node a)
35 {
36     return a.x>0&&a.x<=n&&a.y>0&&a.y<=m&&Map[a.x][a.y]!='*'&&!vis[a.x][a.y];
37 }
38 int bfs()
39 {
40     mem(vis,false);
41     priority_queue<node>q;
42     q.push(node(sx,sy,0));
43     vis[sx][sy]=1;
44     while(!q.empty())
45     {
46         cur=q.top();
47         q.pop();
48         if(cur.x==tx&&cur.y==ty)
49         {
50             return cur.step;
51         }
52         f(i,0,3)
53         {
54             nxt=cur;
55             nxt.x+=dir[i][0];
56             nxt.y+=dir[i][1];
57             nxt.step++;
58             if(nxt.x<1||nxt.x>n||nxt.y<1||nxt.y>m||Map[nxt.x][nxt.y]=='*')continue;
59             if(vis[nxt.x][nxt.y])continue;
60             if(Map[nxt.x][nxt.y]=='|'||Map[nxt.x][nxt.y]=='-')//只要有楼梯就经过的原则,不放过任何一种状态 
61             {
62                 char c=Map[nxt.x][nxt.y];//注意不能改变Map[cur.x][cur.y]的值,要让它保持原来的状态 
63                 if(nxt.step&1)//步数为奇数时需要变换楼梯 
64                 {
65                     if(c=='|')c='-';
66                     else c='|';
67                  } 
68                 nxt.x+=dir[i][0];
69                 nxt.y+=dir[i][1];
70                 if((c=='|'&&(i<=1))||(c=='-'&&(i>1)))//横向走时楼梯是纵向或者纵向走时楼梯是横向 
71                 {
72                     nxt.step++;
73                 }
74                 if(!ok(nxt))continue;
75                 if(nxt.x<1||nxt.x>n||nxt.y<1||nxt.y>m||Map[nxt.x][nxt.y]=='*')continue;
76                 if(vis[nxt.x][nxt.y])continue;//每次状态(位置)改变时都要查询访问记录 
77             }
78             vis[nxt.x][nxt.y]=1;//注意每次一种状态入队都要设置访问记录 
79             q.push(nxt);
80         }
81     }
82 }
83 int main()
84 {
85     //freopen("input.txt","r",stdin);
86     //freopen("output.txt","w",stdout);
87     std::ios::sync_with_stdio(false);
88     while(scanf("%d%d",&n,&m)!=EOF)
89     {
90         f(i,1,n)
91             f(j,1,m)
92             {
93                 scanf(" %c",&Map[i][j]);
94                 if(Map[i][j]=='S')sx=i,sy=j;
95                 if(Map[i][j]=='T')tx=i,ty=j;
96             }
97         pf("%d
",bfs());
98     }
99  } 
原文地址:https://www.cnblogs.com/randy-lo/p/12509935.html