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个方向 ...
随机推荐
- [Python笔记][第二章Python序列-复杂的数据结构]
2016/1/27学习内容 第二章 Python序列-复杂的数据结构 堆 import heapq #添加元素进堆 heapq.heappush(heap,n) #小根堆堆顶 heapq.heappo ...
- FFmpeg详解
认识FFMPEG FFMPEG堪称自由软件中最完备的一套多媒体支持库,它几乎实现了所有当下常见的数据封装格式.多媒体传输协议以及音视频编解码器.因此,对于从事多媒体技术开发的工程师来说,深入研究FFM ...
- jQuery中$.getJSON的返回值问题
在使用$.getJSON获得数据库的返回值后,想将该值return传给其他函数.结果遇到问题. $.getJSON(url, data, function(result) { return resul ...
- jquery方法详解
jquery方法详解 http://www.365mini.com/doc
- SFTP CONFIGURATION IN FLASHFXP PROGRAM
This is a brief guide on how to configure the FlashFXP FTP client to log on to the domain web space ...
- iOS基本内存管理:autorelease和autoreleasepool
1.autorelease 基本用法 对象执行autorelease方法时会将对象添加到自动释放池中 当自动释放池销毁时自动释放池中所有对象作release操作 对象执行autorelease方法后自 ...
- C#之回到了最初的起点----解决方案、项目、程序集、命名空间
C#之回到了最初的起点----解决方案.项目.程序集.命名空间 ——Percy 初学者很容易把这些概念搞混淆.先说说项目(Project),通俗的说,一个项目可以就是你开发的一个软件.在.Net下,一 ...
- 单光纤udp通信
环境: 两块板子,拥有独立系统(Linux),通过单光纤连接(数据只能单向发送,无反馈).两块板子采用udp协议通信. 问题: 发送板子发送数据后,接收板子上的进程收不到数据. 确认两块光纤 ...
- 移动端-弹窗demo
<!doctype html> <html> <head> <meta charset="UTF-8"> <meta name ...
- ORACLE 绑定变量用法总结 .
之前对ORACLE中的变量一直没个太清楚的认识,比如说使用:.&.&&.DEIFINE.VARIABLE……等等.今天正好闲下来,上网搜了搜相关的文章,汇总了一下,贴在这里,方 ...