HDU 1180 诡异的楼梯

  1 #include<iostream>  
  2 #include<cstdio>  
  3 #include<cstring>  
  4 #include<algorithm>  
  5 #include<queue>  
  6   
  7 using namespace std;  
  8   
  9 struct node  
 10 {  
 11     int x,y,t;  
 12     bool operator<(const node& a)const  
 13     {  
 14         return t>a.t;  
 15     }  
 16 };  
 17   
 18 int n,m;  
 19 char g[30][30];  
 20 bool vis[30][30];  
 21 int x1,y1,x2,y2;  
 22 int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};  
 23   
 24 bool jud(node k)  
 25 {  
 26     if(k.x<0||k.x>=n||k.y<0||k.y>=m)  
 27         return false;  
 28     if(g[k.x][k.y]=='*')  
 29         return false;  
 30     if(vis[k.x][k.y])  
 31         return false;  
 32     return true;  
 33 }  
 34   
 35 int bfs()  
 36 {  
 37     node a,k;  
 38     priority_queue<node> q;  
 39     a.x=x1,a.y=y1,a.t=0;  
 40     q.push(a);  
 41     vis[x1][y1]=1;  
 42     while(!q.empty())  
 43     {  
 44         a=q.top();  
 45         q.pop();  
 46         for(int i=0;i<4;i++)  
 47         {  
 48             if(g[a.x][a.y]=='-' && a.t%2==0 && (i==2||i==3)) continue; //从前面(后面)过不去
 49             if(g[a.x][a.y]=='-' && a.t%2==1 && (i==0||i==1)) continue;  //从前面(后面)过不去
 50             if(g[a.x][a.y]=='|' && a.t%2==0 && (i==0||i==1)) continue;  //从上面(下面)过不去
 51             if(g[a.x][a.y]=='|' && a.t%2==1 && (i==2||i==3)) continue;  //从上面(下面)过不去
 52             k.x=a.x+dir[i][0];  
 53             k.y=a.y+dir[i][1];  
 54             k.t=a.t+1;  
 55             if(!jud(k)) continue;//该点不可通过或者出界  
 56             if(g[k.x][k.y]=='-')  
 57             {  
 58                 if(a.t%2==0 && (i==3||i==2))  //不能过,等一秒;
 59                 {  
 60                     q.push(k);  
 61                     continue;  
 62                 }  
 63                 else if(a.t%2==1 && (i==0||i==1))  
 64                 {  
 65                     q.push(k);  
 66                     continue;  
 67                 }  
 68                 else  
 69                 {  
 70                     k.t--;  //能过,这点不算时间;(计时从改楼梯开始);
 71                     q.push(k);  
 72                     continue;  
 73                 }  
 74             }  
 75             if(g[k.x][k.y]=='|')  //同'-'
 76             {  
 77                 if(a.t%2==0 && (i==0||i==1))  
 78                 {  
 79                     q.push(k);  
 80                     continue;  
 81                 }  
 82                 else if(a.t%2==1 && (i==2||i==3))  
 83                 {  
 84                     q.push(k);  
 85                     continue;  
 86                 }  
 87                 else  
 88                 {  
 89                     k.t--;  
 90                     q.push(k);  
 91                     continue;  
 92                 }  
 93             }  
 94             if(k.x==x2 && k.y==y2)  
 95                 return k.t;  
 96             vis[k.x][k.y]=1;  //'.'的点;
 97             q.push(k);  
 98         }  
 99     }  
100     return -1;  
101 }  
102   
103 int main()  
104 {  
105     //freopen("1180.txt","r",stdin);
106     while(~scanf("%d%d",&n,&m))  
107     {  
108         int i,j;
109         gets(g[0]);  
110         for( i=0;i<n;i++)  
111             gets(g[i]);  
112         for( i=0;i<n;i++)  
113             for( j=0;j<m;j++)  
114                 if(g[i][j]=='S')  
115                     x1=i,y1=j;  
116                 else if(g[i][j]=='T')  
117                     x2=i,y2=j;  
118         memset(vis,0,sizeof(vis));  
119         int ans=bfs();  
120         printf("%d
",ans);  
121   
122   
123     }  
124     return 0;  
125 }  

 还有 另外一种从 学长那里收集到的代码,这个不需要用到优先队列.

/*

为了分的清楚点...

*/

 1 #include<iostream>
 2 #include<queue>
 3 using namespace std;
 4 #define maxn 21
 5 char maze[maxn][maxn];
 6 int m,n,si,sj,ti,tj;
 7 bool visited[maxn][maxn];
 8 int dir[][2] = {{0,-1},{1,0},{0,1},{-1,0}};
 9 struct node
10 {
11     int x,y,t;
12 };
13 bool ok(int i,int j)
14 {
15     if(i >= 1 && i <= m && j >= 1 && j <= n && maze[i][j] != '*' && !visited[i][j])
16         return true;
17     return false;    
18 }
19 bool canThrough(int i,int j,int dir,int step) //判断能否通过楼梯
20 {
21     int t;
22     if(maze[i][j]=='|')//若为‘|’,设t=1
23         t=1;
24     else
25         t=0;
26 if(step%2)//经过奇数秒后楼梯方向发生变化 27 t++; 28 if((t + dir)%2 == 0)//若楼梯的方向和寻找的方向相同 29 return 1; 30 return 0; 31 } 32 void BFS() 33 { 34 queue<node> Q; 35 node p,q; 36 p.x = si,p.y = sj,p.t = 0; 37 Q.push(p); 38 memset(visited,false,sizeof(visited)); 39 visited[p.x][p.y] = true; 40 while(!Q.empty()) 41 { 42 p = Q.front(); 43 Q.pop(); 44 if(p.x == ti && p.y == tj) 45 { 46 printf("%d ",p.t); 47 return; 48 } 49 for(int i = 0; i < 4; i++) 50 { 51 q.x = p.x+dir[i][0],q.y = p.y+dir[i][1],q.t = p.t+1; 52 if(ok(q.x,q.y)) //若合法 53 { 54 if(maze[q.x][q.y] == '.' || maze[q.x][q.y] == 'T') 55 Q.push(q),visited[q.x][q.y] = true; 56 else 57 { 58 if(canThrough(q.x,q.y,i,p.t)) //如果能通过此楼梯,注意时间是p.t,因为q.t在之前以加1 59 { 60 q.x += dir[i][0],q.y += dir[i][1]; //通过此楼梯的方向仍为i 61 if(ok(q.x,q.y)) 62 Q.push(q),visited[q.x][q.y] = true; 63 } 64 else //通不过此楼梯,则再等一秒 65 { 66 q.x += dir[i][0],q.y += dir[i][1]; 67 if(ok(q.x,q.y)) 68 p.t++,Q.push(p); 69 } 70 } 71 } 72 } 73 } 74 } 75 int main() 76 { 77 //freopen("1001.txt","r",stdin); 78 while(scanf("%d%d",&m,&n) != EOF) 79 { 80 int i,j; 81 for(i = 1; i <= m; i++) 82 for(j = 1; j <= n; j++) 83 { 84 cin >> maze[i][j]; 85 if(maze[i][j] == 'S') 86 si = i, sj = j; 87 if(maze[i][j] == 'T') 88 ti = i,tj = j; 89 } 90 BFS(); 91 } 92 return 0; 93 }
原文地址:https://www.cnblogs.com/xiaoniuniu/p/4073729.html