Aizu 2325 Mysterious Maze(SPFA迭代最短路 好的一题)

SDACM训练赛 3 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=45534#overview

题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2325

 

【题意】

给定W*H的迷宫里,给定起点S和终点G,给定N个turn序列(L或者R),要求必须按照这个序列转弯。问能不能到达。

【分析】

比较经典的迷宫最短路问题,这里的序列和费用是turn,转化一下dis【x】【y】 = t 表示走到(x,y)这个格子,用到了turn序列中最小的t位置。然后走到下一步的时候,需要考虑4个方向,预处理cost【t】【k】转入下一个格子。SPFA迭代即可。数据较大,使用STL里的队列模拟。

cost[i][k] =  (k==dir[i])?0 : cost[+1][k]+1;初始cost[n][k] = (k==dir[n])?0 : inf;

 

P.S 比赛的时候没仔细想这个题目,去搞了大坑B题。真是失误。还是得多分析分析题目性质,挖掘出内涵。

 

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<algorithm>
  5 #include <queue>
  6 using namespace std;
  7 
  8 const int maxn = 1010;
  9 const int inf = (1<<30);
 10 int W,H,N;
 11 
 12 char mp[maxn][maxn];
 13 char str[maxn*maxn];
 14 int dir[maxn*maxn];
 15 
 16 int dx[4] = {-1,0,1,0};
 17 int dy[4] = {0,1,0,-1};
 18 
 19 
 20 int cost[maxn*maxn][4];
 21 int dis[maxn][maxn];
 22 bool vis[maxn][maxn];
 23 
 24 struct node{
 25     int x, y;
 26     void init(int __x,int __y)
 27     {
 28         x = __x;y = __y;
 29     }
 30 };
 31 
 32 int Sx,Sy;
 33 int Gx,Gy;
 34 
 35 queue<node>Q;
 36 int main()
 37 {
 38     while (scanf("%d%d%d",&W,&H,&N)==3 && W)
 39     {
 40         scanf("%s",str);
 41 
 42 
 43         dir[0] = 0;
 44         for (int i=1;i<=N;i++)
 45         {
 46             if (str[i-1]=='L'){
 47                 dir[i] = (dir[i-1] + 3) % 4;
 48             }else{
 49                 dir[i] = (dir[i-1] + 1) % 4;
 50             }
 51         }
 52 
 53 
 54         for (int i=0;i<=W+1;i++)
 55         {
 56             for (int j=0;j<=H+1;j++)
 57             {
 58                 mp[i][j] = '#';
 59             }
 60         }
 61         for (int i=1;i<=W;i++)
 62         {
 63             scanf("%s",str);
 64             for (int j=1;j<=H;j++)
 65             {
 66                 mp[i][j] = str[j-1];
 67                 if (mp[i][j]=='S')
 68                 {
 69                     Sx = i;
 70                     Sy = j;
 71                     mp[i][j] = '.';
 72                 }else if (mp[i][j]=='G'){
 73                     Gx = i;Gy = j;
 74                     mp[i][j] = '.';
 75                 }
 76             }
 77         }
 78 #ifdef debug
 79         for (int i=0;i<=W+1;i++)
 80         {
 81             for (int j=0;j<=H+1;j++)
 82             {
 83                 printf("%c",mp[i][j]);
 84             }
 85             puts("");
 86         }
 87         printf("%d %d %d %d\n",Sx,Sy,Gx,Gy);
 88  #endif
 89 
 90         for (int i=N;i>=0;i--)
 91         {
 92             for (int j=0;j<4;j++)
 93             {
 94                 if (dir[i]==j){
 95                     cost[i][j] = 0;
 96                 }else{
 97                     if (i==N){
 98                         cost[i][j] = inf;
 99                     }else{
100                         cost[i][j] = cost[i+1][j] + 1;
101                     }
102                 }
103                 //if (debug)printf("%d %d %d\n",i,j,cost[i][j]);
104             }
105         }
106 
107         node now, cur;
108         int ans = 0;
109         memset(dis, -1, sizeof(dis));
110         memset(vis, 0, sizeof(vis));
111         now.init(Sx,Sy);
112         dis[Sx][Sy] = 0;
113         vis[Sx][Sy] = 1;
114         while (!Q.empty())
115         {
116             Q.pop();
117         }
118         Q.push(now);
119         while (!Q.empty())
120         {
121             cur = Q.front();
122             Q.pop();
123             int dd = dis[cur.x][cur.y];
124             vis[cur.x][cur.y] = 0;
125             for (int k=0;k<4;k++)
126             {
127                 int x = cur.x + dx[k];
128                 int y = cur.y + dy[k];
129                 if (mp[x][y]=='.' && cost[dd][k]<inf){
130                     int tmp = dd + cost[dd][k];
131                     if (dis[x][y]==-1 || tmp < dis[x][y]){
132                         dis[x][y] = tmp;
133                         if (x == Gx && y == Gy)
134                         {
135                             ans = 1;
136                             break;
137                         }
138                         if (!vis[x][y]){
139                             now.init(x,y);
140                             Q.push(now);
141                             vis[x][y] = 1;
142                         }
143                     }
144                 }
145             }
146         }
147        // ans = (dis[Gx][Gy] != -1);
148         puts(ans?"Yes":"No");
149     }
150     return 0;
151 }
aizu 2325

 

转载于:https://www.cnblogs.com/wangsouc/articles/3706431.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值