UVA 1601 The Morning after Halloween
题意:
给出一个最大为16×16的迷宫图和至多3个ghost的起始位置和目标位置,求最少经过几轮移动可以使三个ghost都到达目标位置。每轮移动中,每个ghost可以走一步,也可以原地不动,需要注意的是任意两个ghost不能在相同的位置,也不能出现任意两个ghost对穿。每个迷宫图'#'表示墙,' '表示空地,小写字母表示ghost的起始位置,大写字母表示对应ghost的目标位置。保证任意2×2的空间内都有一个'#'。
分析:
迷宫图给转换成了图,用邻接表保存起来,这样搜索的时候只走可以走的点。根据任意2×2都有'#'这个细节,可以粗略的估计出整个迷宫中可以走的空地不超过200个,3个ghost的话建一个三维数组vis。num数组记录当前是第几个非#地。g[num][0]记录第num个非#地的上下左右有几个非#地。接下来g[num][1]-g[num][num]代表非#地的序号。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
char map[20][20];
int num[20][20];
int g[200][200];
int vis[200][200][200];
int cnt;
int w,h,n;
int que[10000000][4];
int goal[4];
void bfs()
{
memset(vis,0,sizeof(vis));
int fro=0,rear=1;
vis[que[0][1]][que[0][2]][que[0][3]]=true;
while(fro<rear)
{
int i,j,k,t1,t2,t3;
int &step=que[fro][0],&a=que[fro][1],&b=que[fro][2],&c=que[fro][3];
if(a == goal[1] && b == goal[2] && c == goal[3]) { goal[0] = step; return; }
for(i=0;i<=g[a][0];i++)
{
t1=(i==0?a:g[a][i]);
for(j=0;j<=g[b][0];j++)
{
t2=(j==0?b:g[b][j]);
for(k=0;k<=g[c][0];k++)
{
t3=(k==0?c:g[c][k]);
if((t1&&t2&&t1==t2)||(t1&&t3&&t1==t3)||(t2&&t3&&t2==t3))
continue;
if(t1&&t2&&t1==b&&t2==a)
continue;
if(t1&&t3&&t1==c&&t3==a)
continue;
if(t3&&t2&&t3==b&&t2==c)
continue;
if(!vis[t1][t2][t3])
{
vis[t1][t2][t3]=1;
que[rear][0]=step+1,que[rear][1]=t1,que[rear][2]=t2,que[rear][3]=t3;
++rear;
}
}
}
}
++fro;
}
}
int main()
{
while(scanf("%d%d%d",&w,&h,&n)&&w&&h&&n)
{
int i,j,k;
cnt=0;
gets(map[0]);
for(i=0;i<h;i++)
gets(map[i]);
for(i=0;i<h;i++)
for(j=0;j<w;j++)
if(map[i][j]!='#')
num[i][j]=++cnt;
else
num[i][j]=0;
memset(g,0,sizeof(g));
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
{
if(num[i][j])
{
int &pos=num[i][j];
if(num[i+1][j])
g[pos][++g[pos][0]]=num[i+1][j];
if(num[i-1][j])
g[pos][++g[pos][0]]=num[i-1][j];
if(num[i][j+1])
g[pos][++g[pos][0]]=num[i][j+1];
if(num[i][j-1])
g[pos][++g[pos][0]]=num[i][j-1];
}
}
}
que[0][0]=que[0][1]=que[0][2]=que[0][3]=0;
goal[0]=goal[1]=goal[2]=goal[3]=0;
for(i=0;i<h;++i)
{
for(j=0;j<w;++j)
{
if(map[i][j] == 'a')
que[0][1] = num[i][j];
if(map[i][j] == 'b')
que[0][2] = num[i][j];
if(map[i][j] == 'c')
que[0][3] = num[i][j];
}
}
for(i=0;i<h;++i)
{
for(j=0;j<w;++j)
{
if(map[i][j] == 'A')
goal[1] = num[i][j];
if(map[i][j] == 'B')
goal[2] = num[i][j];
if(map[i][j] == 'C')
goal[3] = num[i][j];
}
}
bfs();
printf("%d\n",goal[0]);
}
}
UVA 1601 The Morning after Halloween的更多相关文章
- 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 || 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 ...
- 【Uva 1601】The Morning after Halloween
[Link]: [Description] 给你一张平面图; 最多可能有3只鬼; 给出这几只鬼的初始位置; 然后,这几只鬼有各自的终点; 每秒钟,这几只鬼能同时移动到相邻的4个格子中的一个 任意两只鬼 ...
- UVa 1601 万圣节后的早晨
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- Uva 1061 The Morning after Halloween
基本思路是BFS: 1. 题目中已经说了,每相连的2X2格子中必有一个‘#’,也就是,每个点周围最多也就三个方向可以走.因此,可以把所有空格都提出来,形成一个图,直接遍历每条边,而不是每次判断4个方向 ...
随机推荐
- jQuery支持移动Mobile的DOM元素移动和缩放插件
jQuery Panzoom是一款很有用的HTML DOM元素平移和缩放jQuery和CSS3插件. Panzoom利用CSS transforms 和 matrix函数来为浏览器进行硬件(GPU)加 ...
- stagefright框架(四)-Video Buffer传输流程
這篇文章將介紹Stagefright中是如何和OMX video decoder传送buffer. (1) OMXCodec會在一開始的時候透過read函式來傳送未解碼的data給decoder,並且 ...
- Jquery时间段选择器
效果(有给小bug, 在时间的大小比较上.): HTML: <html> <head> <title>测试DatePicker</title> < ...
- SQL Server 强行Insert包含自增列值的记录
SET IDENTITY_INSERT 表 ON INSERT INTO 表 ([ID] ,[SequenceNumber] ,[EnumCode] ,[Description]) VALUES ( ...
- js库开发--参数传递及方法修改
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> ...
- ASP.NET通用权限验证组件实现
沙发(SF)通用权限验证组件 开篇 本篇介绍通用权限验证的实现代码思路,总共分为导入参数.解析XML.根据XML配置进行处理.返回结果. 代码架构图 1. 类介绍 1.SFWebPermissio ...
- 为什么JavaScript函数中的参数前面不能加var
首先这里是JavaScript的语法规则. 其次在调用function()函数的时候参数时外部传入的.在传入之前就已经被声明了.没必要在函数参数里声明. 如果想要在函数里用新的参数 function( ...
- AngularJS中serivce,factory,provider的区别
一.service引导 刚开始学习Angular的时候,经常被误解和被初学者问到的组件是 service(), factory(), 和 provide()这几个方法之间的差别.This is whe ...
- Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to “*****”
Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment ...
- nginx自定义模块编写-根据post参数路由到不同服务器
nginx可以轻松实现根据不同的url 或者 get参数来转发到不同的服务器,然而当我们需要根据http包体来进行请求路由时,nginx默认的配置规则就捉襟见肘了,但是没关系,nginx提供了强大的自 ...