zoukankan      html  css  js  c++  java
  • kuangbin专题 专题二 搜索进阶 Nightmare Ⅱ HDU

    题目链接: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 }
  • 相关阅读:
    反射
    left join 多个表关联时,将表值置换
    distinct 与 group by 去重
    常见错误
    字符串的处理
    排版样式
    VS低版本打开高版本解决方案(如08打开10、12、13版本vs编译的项目)
    Dw CS 破解
    VS2013如何避开安装时IE10的限制
    UVa540 Team Queue
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/11184147.html
Copyright © 2011-2022 走看看