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 }

原文地址:https://www.cnblogs.com/SSummerZzz/p/11184147.html

时间: 2024-08-02 08:52:47

kuangbin专题 专题二 搜索进阶 Nightmare Ⅱ HDU - 3085的相关文章

kuangbin带你飞专题一 简单搜索 题解

目录 [kuangbin带你飞]专题一 简单搜索 [kuangbin带你飞]专题一 简单搜索 总结:用时2天半终于把这个专题刷完了 对于最基础的dfs bfs 路径打印 状态转移也有了一点自己些微的理解 其实2天半可以压缩到1天半的 主要是自己太懒了...慢慢加油刷bin神的专题呀 从大二下学期开始学算法 一开始就知道这个专题 一开始对于这个专题里的所有问题感觉都好难啊..就直接放弃了 看lrj的书 现在看到这个专题还挺唏嘘的吧 突然觉得思维和想法也不是很难 果然是那个时候心不静&还是储量不够吗

「kuangbin带你飞」专题十二 基础DP

layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathjax: true - kuangbin - 动态规划 传送门 A.HDU1024 Max Sum Plus Plus 题意 给你N个数,然后你分成M个不重叠部分,并且这M个不重叠部分的和最大. 思路 动态规划最大m字段和,dp数组,dp[i][j]表示以a[j]结尾的,i个字段的最大和 两种情况:1.第a[j

kuangbin专题 专题九 连通图 HDU 4738 Caocao&#39;s Bridges

题目链接:https://vjudge.net/problem/HDU-4738 题目:tarjan求桥,坑点: 题目说是分岛任务...如果所有岛之间没有完全连通,就不需要执行任务了...答案直接是0... 桥上可能没人,但是,炸弹需要一个人去送,所以至少1个人. 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 6 const int N

专题一 简单搜索

本专题主要锻炼搜索的两大方法——bfs (宽度优先搜索)和 dfs (深度优先搜索) ===================================华丽的分割线======================================= 一.bfs——宽度优先搜索 bfs主要运用于搜索中求最短时间的问题,搜索过程中一般需要运用 queue 的操作.具体的操作如下: 1.首先需要将 队列 和 visit数组 清空.(这一点很重要!!!) 2.然后将起点信息 push 进队列,标记为vis

Android开发之图片处理专题(二):利用AsyncTask和回调接口实现图片的异步加载和压缩

在上一篇专题Android开发之图片处理专题(一):利用软引用构建图片高速缓存中我们讲述了如何利用软引用技术构建高速缓存.那么想要用到图片,首先得有图片的来源.一般而言,一个应用的图片资源都是从服务器处获得的.今天,我们利用Android开发之网络请求通信专题(二):基于HttpClient的文件上传下载里面封装好的httpUtils来实现图片的下载,然后加载到本地配合软引用缓存使用,以一个listView为例子来说明. 一.准备工作 我们需要准备以下几个类(图片对象和软引用缓存类请参考上一篇专

【开源夏令营优秀开题报告】专题之二 - 嵌入式与智能硬件类合集

CSDN开源夏令活动已经正式进入第一实习阶段,我们遴选出部分优秀提案开题报告进行展示.本文是嵌入式与智能硬件类开题报告展示. 编者按:CSDN开源夏令活动,已经正式进入第一实习阶段,我们遴选出了部分提案的优秀开题报告进行展示.优秀开题报告作者将得到CSDN高校俱乐部发出的"2014开源夏令营荣誉证书"及纪念品一份. 提案1:环境数据采集系统  提案简介:该项目是一套利用物联网技术对环境数据进行采集.处理的综合系统:其利用传感器网络,收集环境中的温度.湿度.光照度.风速.紫外线强度.粉尘

kuangbin专题专题四 Til the Cows Come Home POJ - 2387

题目链接:https://vjudge.net/problem/POJ-2387 题意:从编号为n的城市到编号为1的城市的最短路. 思路:dijkstra模板题,直接套板子,代码中我会带点注释给初学者看. 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include <string> 6 using namespac

搜索进阶

搜索进阶的话,我觉得A*,IDA*,双向BFS应该都是吧. 双向BFS就是同时从起点和终点开始BFS,直到遇到对方标记的结点就停止(这样应该不一定是最短路),这样的话只要有解就可以减去很多种可能,从而提高效率. 不过如果没解的话,两边的搜索没有交叉,也就...会更慢... 然后就是A*,这算是人工智能里面的了吧...就是F(n)=G(n)+H(n),这里G一般就是节点的深度,也就是走了多少步走到了这里,H的话就是一个估计,估计还有差不多多少步就会走完,然后这两个加起来,作为一个依据,那么下一次要

开发指南专题专题一: JEECG微云快速开发平台前言

JEECG微云快速开发平台-前言 1. 前言 1.1. 技术背景 随着WEB UI 框架(EasyUI/Jquery UI/Ext/DWZ)等的逐渐成熟,系统界面逐渐实现统一化,代码生成器也可以生成统一规范的界面! 代码生成+手工MERGE半智能开发将是新的趋势,生成的代码可节省50%工作量,快速提高开发效率! 1.2. 平台介绍 JEECG [J2EE  Code Generation] 是一款基于代码生成器的微信快速开发平台,采用代码生成+手工MERGE半智能开发模式, 可以帮助解决Java