kuangbin专题 专题二 搜索进阶 Nightmare Ⅱ HDU - 3085

Posted ssummerzzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kuangbin专题 专题二 搜索进阶 Nightmare Ⅱ HDU - 3085相关的知识,希望对你有一定的参考价值。

 

题目链接:https://vjudge.net/problem/HDU-3085

题意:有两个鬼和两个人和墙,鬼先走,人再走,鬼每走过的地方都会复制一个新鬼,

但新鬼只能等待旧鬼走完一次行程之后,下一次旧鬼再次开始新的行程时旧鬼才能移动,

旧鬼一个行程能走最多两步,M能走三步,G能走一步。

问M和G能不能在被鬼抓住之前相遇,求最短时间。

‘Z’表示鬼。

第一次用曼哈顿距离来真正解决搜索,参考过别人的代码,这份代码感觉还是比较清楚和简单的。

人每次移动一个距离都要进行一次曼哈顿距离的判断,判断人到该点时,是不是在鬼之前先到达,

注意,鬼先移动一个行程,人再移动一个行程。


  1 #include <iostream>
  2 #include <cstring>
  3 #include<vector>
  4 #include <cstdio>
  5 #include<string>
  6 #include <cmath>
  7 #include <map>
  8 #include <queue>
  9 #include <algorithm>
 10 using namespace std;
 11 
 12 #define inf (1LL << 31) - 1
 13 #define rep(i,j,k) for(int i = (j); i <= (k); i++)
 14 #define rep__(i,j,k) for(int i = (j); i < (k); i++)
 15 #define per(i,j,k) for(int i = (j); i >= (k); i--)
 16 #define per__(i,j,k) for(int i = (j); i > (k); i--)
 17 
 18 const int N  = 810;
 19 int mv_x[] = 0, 0, 1, -1;
 20 int mv_y[] = 1, -1, 0, 0;
 21 char mp[N][N]; //原始地图
 22 int mx,my,hx,hy; //男女的坐标
 23 int g_x[2],g_y[2],g_l; //两个鬼的坐标
 24 int n,m,STEP;
 25 
 26 struct node
 27     int x,y;
 28 ;
 29 
 30 queue <node > que[2];
 31 queue <node > qt;
 32 
 33 inline void init()
 34     g_l = 0;
 35     STEP = 0;
 36 
 37 
 38 void input()
 39 
 40     init();
 41 
 42     rep(i,1,n)
 43         rep(j,1,m)
 44             cin >> mp[i][j];
 45             if(mp[i][j] == M) mx = i, my = j;
 46             else if(mp[i][j] == G) hx = i, hy = j;
 47             else if(mp[i][j] == Z) g_x[g_l] = i, g_y[g_l++] = j;
 48         
 49     
 50 
 51 
 52 //是否越界
 53 inline bool check(int x, int y)
 54     return x >= 1 && x <= n && y >= 1 && y <= m;
 55 
 56 
 57 //曼哈顿距离判断能不能相遇
 58 inline bool M_dis(int dx,int dy)
 59 
 60     rep__(i,0,2)
 61         if(abs(dx - g_x[i]) + abs(dy - g_y[i]) <= 2 * STEP) return false;
 62     
 63     return true;
 64 
 65 
 66 void show()
 67 
 68     rep(i,1,n)
 69         rep(j,1,m) cout << mp[i][j];
 70         cout << endl;    
 71     
 72 
 73 
 74 bool bfs(int pos, int steps, char me, char another)
 75 
 76     
 77 
 78     rep(i,1,steps) //一个行程走几轮
 79         qt = que[pos];  //把这轮的所有开始点复制给qt
 80 
 81         while(!qt.empty())
 82 
 83             node tmp = qt.front();
 84             qt.pop();
 85             que[pos].pop();
 86 
 87             if(!M_dis(tmp.x,tmp.y)) continue; //刚开始进入bfs判断一次曼哈顿距离,先判断下人没走之前鬼是不是能抓到人
 88 
 89             rep__(p,0,4)
 90                 
 91                 int dx = tmp.x + mv_x[p];
 92                 int dy = tmp.y + mv_y[p];
 93 
 94                 //没越界   不是墙  不是鬼  自己没走过  满足曼哈顿距离
 95                 if(check(dx, dy) && mp[dx][dy] != X && mp[dx][dy] != Z &&  mp[dx][dy] != me
 96                                                    && M_dis(dx,dy))
 97                     
 98                     if(mp[dx][dy] == another) //遇到了另一个人
 99 
100                         // cout << "find the position  " << dx << "  " << dy << endl;
101                         // cout << me  <<" find " << mp[dx][dy] << endl;
102                         return true;
103                     
104 
105                     mp[dx][dy] = me; //标记自己走过了这里
106                     que[pos].push(node dx, dy );//存在que[]中,表示下一轮的开始点
107                 
108             
109         
110     
111 
112     return false;
113 
114 
115 bool solve()
116 
117     while (!que[0].empty()) que[0].pop();
118     while (!que[1].empty()) que[1].pop();
119     while (!qt.empty()) qt.pop();
120   //que[0]表示M,que[1]表示G
121     que[0].push(node mx, my );
122     que[1].push(node hx, hy );
123 
124     while (!que[0].empty() && !que[1].empty()) // && 和 ||  其实都可以  &&说明一个人不能走了 
                               //那么另一个人也一定没地方走了
125 126 STEP++;//步数加一,其实更好理解为行程加一 127 if(bfs(0, 3,M,G) || bfs(1, 1,G,M)) return true; 128 129 130 131 return false; 132 133 134 int main() 135 136 ios::sync_with_stdio(false); 137 cin.tie(0); 138 139 int T; 140 cin >> T; 141 while (T--) 142 cin >> n >> m; 143 input(); 144 145 if(solve()) cout << STEP << endl; 146 else cout << "-1" << endl; 147 // show(); 148 // cout << endl; 149 150 151 // getchar(); 152 153 return 0; 154

 

以上是关于kuangbin专题 专题二 搜索进阶 Nightmare Ⅱ HDU - 3085的主要内容,如果未能解决你的问题,请参考以下文章

[kuangbin]各种各样的题单

kuangbin专题一 简单搜索 翻转(POJ-3279)

kuangbin专题一 简单搜索 石油储备(HDU-1241)

「kuangbin带你飞」专题二十二 区间DP

「kuangbin带你飞」专题二十 斜率DP

kuangbin专题总结一 简单搜索