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 }
  • 相关阅读:
    龙井和碧螺春的功效与作用
    064 01 Android 零基础入门 01 Java基础语法 08 Java方法 02 无参带返回值方法
    063 01 Android 零基础入门 01 Java基础语法 08 Java方法 01 无参无返回值方法
    062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用
    061 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 08 一维数组总结
    060 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 07 冒泡排序
    059 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 06 增强型for循环
    058 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 05 案例:求数组元素的最大值
    057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和
    056 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 03 一维数组的应用
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/11184147.html
Copyright © 2011-2022 走看看