【例题 7-9 UVA-1601】The Morning after Halloween
【链接】 我是链接,点我呀:)
【题意】
在这里输入题意
【题解】
对于没有出现的,当成0节点就好。
所以总是认为有3个人需要走到各自的终点。
将平面图转成点边图。这样比较好枚举。
(二维变成一维,模拟的时候变量都少了一半啦)
然后每次按照要求模拟走一下就好。
(三重循环,枚举每一个人下一步走到了哪个位置即可
(注意两个0节点可以走到相同的位置->因为实际上他们都不存在);
然后用一个三元组加入队列里。
f[x][y][z]来判重就好了。
(直接用map来判重会TLE到死。。
【代码】
/*
1.Shoud it use long long ?
2.Have you ever test several sample(at least therr) yourself?
3.Can you promise that the solution is right? At least,the main ideal
4.use the puts("") or putchar() or printf and such things?
5.init the used array or any value?
6.use error MAX_VALUE?
7.use scanf instead of cin/cout?
8.whatch out the detail input require
*/
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,pair<int,int> > piii;
const int N = 256;
const int NN = 16;
const int dx[4] = {0,0,1,-1};
const int dy[4] = {1,-1,0,0};
int n,m,tot;
int v[3][2];
char s[NN+5][NN+5];
vector <int> g[N+10];
int dic[N+10][N+10][N+10];
queue <piii> dl;
bool jue(int x,int y){
if (x==0 || y==0) return false;
if (x==y) return true;
return false;
}
int main(){
#ifdef LOCAL_DEFINE
freopen("F:\\c++source\\rush_in.txt", "r", stdin);
freopen("F:\\c++source\\rush_out.txt", "w", stdout);
#endif
ios::sync_with_stdio(0),cin.tie(0);
while (cin >> m>> n >> tot){
if (n==0 && m==0 && tot==0) break;
cin.get();
memset(v,0,sizeof v);
for (int i = 0;i <=N;i++) g[i].clear();
for (int i = 0;i <= N;i++) g[i].push_back(i);
for (int i = 1;i <= n;i++) cin.getline(s[i]+1,N+10);
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
if (s[i][j]!='#'){
for (int k = 0;k < 4;k++){
int ti = i + dx[k],tj = j + dy[k];
if (ti >=1 && ti <= n && tj>=1 && tj<=m && s[ti][tj]!='#'){
int x = (i-1)*m+j,y = (ti-1)*m+tj;
g[x].push_back(y);
}
}
for (int k = 0;k < tot;k++){
if (s[i][j]==('a'+k)) v[k][0] = (i-1)*m+j;
if (s[i][j]==('A'+k)) v[k][1] = (i-1)*m+j;
}
}
memset(dic,-1,sizeof dic);
dic[v[0][0]][v[1][0]][v[2][0]] = 0;
piii temp = make_pair(v[0][0],make_pair(v[1][0],v[2][0]));
dl.push(temp);
while (!dl.empty()){
temp = dl.front();
dl.pop();
int x = temp.first,y = temp.second.first,z = temp.second.second;
for (int i = 0;i < (int)g[x].size();i++)
for (int j = 0;j < (int)g[y].size();j++)
for (int k = 0;k < (int)g[z].size();k++){
int tx = g[x][i],ty = g[y][j],tz = g[z][k];
if (jue(tx,ty) || jue(tx,tz) || jue(ty,tz)) continue;
if (!(x==0||y==0)&&x == ty && tx == y) continue;
if (!(x==0||z==0)&&x == tz && tx == z) continue;
if (!(y==0||z==0)&&y == tz && ty == z) continue;
piii temp1 = make_pair(tx,make_pair(ty,tz));
if (dic[tx][ty][tz]==-1){
dic[tx][ty][tz] = dic[x][y][z] + 1;
dl.push(temp1);
}
}
}
cout << dic[v[0][1]][v[1][1]][v[2][1]] <<endl;
}
return 0;
}
【例题 7-9 UVA-1601】The Morning after Halloween的更多相关文章
- UVA 1601 The Morning after Halloween
题意: 给出一个最大为16×16的迷宫图和至多3个ghost的起始位置和目标位置,求最少经过几轮移动可以使三个ghost都到达目标位置.每轮移动中,每个ghost可以走一步,也可以原地不动,需要注意的 ...
- UVA - 1601 The Morning after Halloween (BFS/双向BFS/A*)
题目链接 挺有意思但是代码巨恶心的一道最短路搜索题. 因为图中的结点太多,应当首先考虑把隐式图转化成显式图,即对地图中可以相互连通的点之间连边,建立一个新图(由于每步不需要每个鬼都移动,所以每个点需要 ...
- UVA - 1601 The Morning after Halloween (双向BFS&单向BFS)
题目: w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...
- <<操作,&0xff以及|的巧妙运用(以POJ3523---The Morning after Halloween(UVa 1601)为例)
<<表示左移,如a<<1表示将a的二进制左移一位,加一个0,&0xff表示取最后8个字节,如a&0xff表示取a表示的二进制中最后8个数字组成一个新的二进制数, ...
- [uva P1601] The Morning after Halloween
[uva P1601] The Morning after Halloween 题目链接 非常经典的一道题目,lrj的书上也有(貌似是紫书?). 其实这题看起来就比较麻烦.. 首先要保证小鬼不能相遇, ...
- UVa 1601 万圣节后的早晨
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 【UVa】1601 The Morning after Halloween(双向bfs)
题目 题目 分析 双向bfs,对着书打的,我还调了好久. 代码 #include<cstdio> #include<cstring> #include<c ...
- uva 1601 poj 3523 Morning after holloween 万圣节后的早晨 (经典搜索,双向bfs+预处理优化+状态压缩位运算)
这题数据大容易TLE 优化:预处理, 可以先枚举出5^3的状态然后判断合不合法,但是由于题目说了有很多墙壁,实际上没有那么多要转移的状态那么可以把底图抽出来,然后3个ghost在上面跑到时候就不必判断 ...
- 【Uva 1601】The Morning after Halloween
[Link]: [Description] 给你一张平面图; 最多可能有3只鬼; 给出这几只鬼的初始位置; 然后,这几只鬼有各自的终点; 每秒钟,这几只鬼能同时移动到相邻的4个格子中的一个 任意两只鬼 ...
- UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)
题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...
随机推荐
- tensorflow学习之路----保存和提取数据
#保存数据注意他只能保存变量,不能保存神经网络的框架.#保存数据的作用:保存权重有利于下一次的训练,或者可以用这个数据进行识别#np.arange():arange函数用于创建等差数组,使用频率非常高 ...
- python垃圾回收算法
标准python垃圾回收器由两部分组成,即引用计数回收器和分代垃圾回收器(即python包中的gc module).其中,引用计数模块不能被禁用,而GC模块可以被禁用. 引用计数算法 python中每 ...
- 紫书 例题 9-4 UVa 116 ( 字典序递推顺序)
这道题在递推方式和那个数字三角形有一点相像,很容易推出来 但是这道题要求的是字典序,这里就有一个递推顺序的问题 这里用逆推,顺推会很麻烦,为什么呢? 如果顺推的话,最后一行假设有种情况是最小值,那么你 ...
- 解决 php7 cli 模式下中文乱码的两中方法
解决 php7 cli 模式下中文乱码的两中方法1. 给PHP文件开头加上 exec('chcp 936'); 然后把该文件以 ANSI 格式编码2. 在 php.ini 中设置 default_ch ...
- Mysql主从级联复制
场景1 如果主节点已经运行了一段时间,且有大量数据时,如何配置并启动slave节点 通过备份恢复数据至从服务器· 复制起始位置为备份时,二进制日志文件及其POS: Mater 设置 1) 修改配置文件 ...
- C# 开发 —— 数组类对象接口
数组类型是从抽象基类 Array 派生的引用类型,通过new运算符创建数组并将数组元素初始化为他们的默认值 一维数组 type[] arrayname; 数组的长度不是声明的一部分,而且数组必须在访问 ...
- useradd---创建的新的系统用户
useradd命令 useradd命令用于Linux中创建的新的系统用户.useradd可用来建立用户帐号.帐号建好之后,再用passwd设定帐号的密码.而可用userdel删除帐号.使用user ...
- java 参数
-Xmx:size java最大堆内存 -Xms:size 初始化内存 -Xmn:size 年轻带堆大小 -XX:NewSize=size 年轻带的大小 -XX:NewRatio=ratio 年轻带和 ...
- Java生产者与消费者(上)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 生产与消费者模式,是编程中最常用的模式之一,在多线程中应用比较明显.个人理解:在自助餐厅,厨师在不断 ...
- 洛谷 P2242 公路维修问题
P2242 公路维修问题 题目描述 由于长期没有得到维修,A国的高速公路上出现了N个坑.为了尽快填补好这N个坑,A国决定对M处地段采取交通管制.为了求解方便,假设A国的高速公路只有一条,而且是笔直的. ...