[uva P1601] The Morning after Halloween
[uva P1601] The Morning after Halloween
非常经典的一道题目,lrj的书上也有(貌似是紫书?)。
其实这题看起来就比较麻烦。。
首先要保证小鬼不能相遇,也不能互相穿过。
可以用一个vis[][][]数组来表示三个小鬼的当前处于位置是否已经访问,
dis[][][]表示到某个状态是最小步数,用short存,可以卡住空间。
但是这样效率不高。注意到每四个格子里面至少有一个‘#’,所以我们可以把原来的网格图建一个隐式图,就可以避开很多冗余判断。
为了提高效率,我用了双向bfs。
其实就是在原来bfs基础上加点东西,代码量还是有点长的。
据说我的空间还是很大,在某些oj上会被卡。。所以还需要更优秀的标记。
code:
%:pragma GCC optimize()
#include<bits/stdc++.h>
#define idx(i,j) ((i)*m+(j))
#define Ms(a,x) memset(a,x,sizeof a)
using namespace std;
,P=,fl[][]={{,},{-,},{,},{,-},{,}};
],lays;}cur,nxt;
],C[P]; char ch,a[N][N];
short vis[P][P][P],dis[P][P][P];
queue <sta> Q[];
inline char read() {
ch=getchar();
while (ch!=' '&&ch!='#'&&!isalpha(ch)) ch=getchar();
return ch;
}
void add(int u,int v) {G[u][C[u]++]=v;}
bool jug(int x,int y) {
||x>n-||y<||y>m-) ;
return a[x][y]!='#';
}
int update(int id) {
]][nxt.p[]][nxt.p[]]==-) {
vis[nxt.p[]][nxt.p[]][nxt.p[]]=id;
dis[nxt.p[]][nxt.p[]][nxt.p[]]=nxt.lays;
Q[id].push(nxt);
;
}]][nxt.p[]][nxt.p[]]==-id)
]][nxt.p[]][nxt.p[]];
;
}
int bfs(int id,int s) {
while (!Q[id].empty()) {
cur=Q[id].front();
;
Q[id].pop();
) {
nxt=cur,nxt.lays=s+;
,s1=C[cur.p[]]; i<s1; i++) {
nxt.p[]=G[cur.p[]][i];
int re=update(id);
if (~re) return re;
}
}else
) {
nxt=cur,nxt.lays=s+;
,s1=C[cur.p[]]; i<s1; i++) {
nxt.p[]=G[cur.p[]][i];
,s2=C[cur.p[]]; j<s2; j++) {
nxt.p[]=G[cur.p[]][j];
]==nxt.p[]) continue;
]==cur.p[]&&nxt.p[]==cur.p[]) continue;
int re=update(id);
if (~re) return re;
}
}
}else
) {
nxt=cur,nxt.lays=s+;
,s1=C[cur.p[]]; i<s1; i++) {
nxt.p[]=G[cur.p[]][i];
,s2=C[cur.p[]]; j<s2; j++) {
nxt.p[]=G[cur.p[]][j];
]==nxt.p[]) continue;
]==cur.p[]&&nxt.p[]==cur.p[]) continue;
,s3=C[cur.p[]]; k<s3; k++) {
nxt.p[]=G[cur.p[]][k];
]==nxt.p[]||nxt.p[]==nxt.p[]) continue;
]==cur.p[]&&nxt.p[]==cur.p[]) continue;
]==cur.p[]&&nxt.p[]==cur.p[]) continue;
int re=update(id);
if (~re) return re;
}
}
}
}
}
;
}
int double_bfs() {
].empty()) Q[].pop();
].empty()) Q[].pop();
Ms(vis,-),Ms(dis,);
; i<; i++) cur.p[i]=; cur.lays=;
; i<n; i++)
; j<m; j++)
if (isupper(a[i][j])) cur.p[a[i][j]-'A']=idx(i,j);
Q[].push(cur),vis[cur.p[]][cur.p[]][cur.p[]]=;
; i<; i++) cur.p[i]=; cur.lays=;
; i<n; i++)
; j<m; j++)
if (islower(a[i][j])) cur.p[a[i][j]-'a']=idx(i,j);
Q[].push(cur),vis[cur.p[]][cur.p[]][cur.p[]]=;
; !Q[].empty()&&!Q[].empty(); st++) {
,st),tag1=bfs(,st);
if (~tag0) return tag0;
if (~tag1) return tag1;
}
;
}
int main() {
while (scanf("%d%d%d",&m,&n,&t)!=EOF,n|m|t) {
; i<n; i++)
; j<m; j++)
a[i][j]=read(),C[idx(i,j)]=;
; i<n; i++)
; j<m; j++)
; k<; k++) {
],j+fl[k][])) continue;
add(idx(i,j),idx(i+fl[k][],j+fl[k][]));
}
printf("%d\n",double_bfs());
}
;
}
[uva P1601] The Morning after Halloween的更多相关文章
- UVA 1601 The Morning after Halloween
题意: 给出一个最大为16×16的迷宫图和至多3个ghost的起始位置和目标位置,求最少经过几轮移动可以使三个ghost都到达目标位置.每轮移动中,每个ghost可以走一步,也可以原地不动,需要注意的 ...
- Uva 1061 The Morning after Halloween
基本思路是BFS: 1. 题目中已经说了,每相连的2X2格子中必有一个‘#’,也就是,每个点周围最多也就三个方向可以走.因此,可以把所有空格都提出来,形成一个图,直接遍历每条边,而不是每次判断4个方向 ...
- 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 11237 - Halloween treats(抽屉原理)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u011328934/article/details/37612503 题目链接:uva 11237 ...
- UVA 11237 - Halloween treats(鸽笼原理)
11237 - Halloween treats option=com_onlinejudge&Itemid=8&page=show_problem&category=516& ...
- UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)
题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...
- 【UVa】1601 The Morning after Halloween(双向bfs)
题目 题目 分析 双向bfs,对着书打的,我还调了好久. 代码 #include<cstdio> #include<cstring> #include<c ...
随机推荐
- [svc]共享内存
ipc是什么? 进程间通信(IPC,Inter-Process Communication),指至少两个进程或线程间传送数据或信号的一些技术或方法. 进程间为何不能直接共享数据? 如何解决ipc问题? ...
- 3.1.2 Spring之IoC
二.Spring之IoC 1. IoC与DI (1) IoC 控制反转( IoC, Inversion of Control) , 是一个概念, 是一种思想. 控制反转就是对对象控制权的转移, 从程序 ...
- openshift 容器云从入门到崩溃之八《日志聚合》
日志可以分为两部分 业务日志 业务日志一般是要长期保留的,以供以后有问题随时查询,elk是现在比较流行的日志方案,但是容器日志最好不要落地所以不能把logstash客户端包在容器里面 可以使用logs ...
- Python:判断文本中的用户名在数据库中是否存在,存在返回1,不存在返回0
下面是我写的python的一个小脚本,作用是:判断文本中的用户名在数据库中是否存在,存在返回1,不存在返回0.用的是MySQL数据库. 要注意的是:strip函数的使用,该函数的作用是去除字符串两端多 ...
- windows程序设计 vs2012 新建win32项目
1.文件->新建->项目 2.选择win32项目,确定 3.下一步 4.选择windows应用程序,选中空项目,安全开发生命周期不选.点击完成. 5.空项目建好了.
- jqueryd的post传递表单以及取消表单的默认传递
//取消表单的默认传递: <form method="post" onsubmit="return false;"> 在FORM属性里添加 onsu ...
- TCP三次握手--syn攻击
TCP握手协议 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确 ...
- js 二维数组 for 循环重新赋值
javascript 二维数组的重新 组装 var arr = [[1,2],[3,4],[5,6],[7,8]]; var temp = new Array(); for(var i= 0 ;i&l ...
- 【 记忆网络 2 】 End-to-End Memory Network
继上一篇:Memory Network 1. 摘要 引入了一个神经网络,在一个可能很大的外部记忆上建立了一个recurrent attention模型. 该体系结构是记忆网络的一种形式,但与该工作中的 ...
- jQuery 筛选器2
jQuery 筛选器2 // 由于$()只能输入字符串$('#li:eq(1)'),可通过.eq()来传入. // 获取this标签中的指定属性 $(this).eq(1) // 获取第一个元素 $( ...