[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 ...
随机推荐
- 20190422 SQL SERVER 服务
-- 数据库服务-- SQL Server(MSSQLSERVER)是必须要开启的,这个是数据库引擎服务,就像汽车的发动机一样-- SQL Server代理(MSSQLSERVER)是代理服务,比如你 ...
- oracle 日期取 月 日
今天碰到只要取月份和天数,如果月份前面有0要去掉0.比如说2010-01-08 ,需要的结果是1-8. 引出了一系列的sql语句 第一: 利用to_number的函数转换自动截0 select to_ ...
- phpstorm----------phpstorm2017基本使用
1.关闭2017版本的,函数参数提示.关闭方式如下: 2.如何设置代码里面的变量等号对齐,和key => value 对齐 ctrl+alt+l 3.修改PHP文件类创建的默认注释 4. ...
- SpringBoot项目启动时链接数据库很慢
SpringBoot项目启动时链接数据库很慢 springboot项目在启动时候,如下图所示,链接数据库很慢 解决方法:在mysql 的配置文件中 配置 skip-name-resolve
- shell bash-shell
bash shell中的命令替换,`cmd`或者$(cmd). bash shell中的变量赋值,直接name = var: (bash中的变量赋值不能中间有空格) 变量引用时,$name,如果na ...
- Centos7.2 Install subversion server
l 安装svn yum install subversion l 查看svn版本 svnserve --version l 创建svn版本库目录 mkdir -p /projects/ ...
- rsync 守护进程备份报错
[root@nfs01 backup]# rsync -avz /backup rsync_backup@172.16.1.41::backupPassword: @ERROR: auth fail ...
- Scala 偏函数
如果你想定义一个函数,而让它只接受和处理其参数定义域范围内的子集,对于这个参数范围外的参数则抛出异常,这样的函数就是偏函数(顾名思异就是这个函数只处理传入来的部分参数). 偏函数是个特质其的类型为Pa ...
- Hdu2041 超级楼梯 (斐波那契数列)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2041 超级楼梯 Time Limit: 2000/1000 MS (Java/Others) M ...
- P2P原理(转)
P2P(Peer to Peer)对等网络 P2P技术属于覆盖层网络(Overlay Network)的范畴,是相对于客户机/服务器(C/S)模式来说的一种网络信息交换方式.在C/S模式中,数据的分发 ...