题目

题目

 


 

分析

双向bfs,对着书打的,我还调了好久。

 


 

代码

#include<cstdio>
#include<cstring>
#include<cctype>
#include<queue>
using namespace std; const int maxs=20,maxn=150;
const int dx[]={1,-1,0,0,0},dy[]={0,0,1,-1,0};
int s[3],t[3];
int deg[maxn],G[maxn][5];
int dis[maxn][maxn][maxn],dis_back[maxn][maxn][maxn];
int id[maxn][maxn]; inline int ID(int a,int b,int c)
{
return (a<<16)|(b<<8)|c;
} inline bool conflict(int a,int b,int a2,int b2)
{
return a2==b2 || (a2==b && b2==a);
} int bfs(queue<int>& q,int d[maxn][maxn][maxn])
{
int u=q.front(); q.pop();
int a = (u>>16)&0xff, b = (u>>8)&0xff, c = u&0xff;
if(dis[a][b][c]!=-1 && dis_back[a][b][c]!=-1) return dis[a][b][c]+dis_back[a][b][c];
for(int i=0;i<deg[a];i++)
{
int a2=G[a][i];
for(int j=0;j<deg[b];j++)
{
int b2=G[b][j];
if(conflict(a,b,a2,b2)) continue;
for(int k=0;k<deg[c];k++)
{
int c2=G[c][k];
if(conflict(a,c,a2,c2)) continue;
if(conflict(b,c,b2,c2)) continue;
if(d[a2][b2][c2]!=-1) continue;
d[a2][b2][c2]=d[a][b][c]+1;
q.push(ID(a2,b2,c2));
}
}
}
return -1;
} int solve()
{
queue<int> q;
q.push(ID(s[0],s[1],s[2]));
memset(dis,-1,sizeof(dis));
dis[s[0]][s[1]][s[2]]=0; queue<int> q_back;
q_back.push(ID(t[0],t[1],t[2]));
memset(dis_back,-1,sizeof(dis_back));
dis_back[t[0]][t[1]][t[2]]=0; int ans,t=0;
while(1)
{
t++;
ans=bfs(q,dis);
if(ans!=-1) return ans;
ans=bfs(q_back,dis_back);
if(ans!=-1) return ans;
} return -1;
}
int main()
{
int w,h,n;
while(scanf("%d%d%d",&w,&h,&n)==3 && n)
{
getchar();
char maze[20][20];
for(int i=0;i<h;i++) fgets(maze[i],20,stdin); int cnt=0,x[maxn],y[maxn],id[maxs][maxs];
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
{
char ch=maze[i][j];
if(ch!='#')
{
x[cnt]=i; y[cnt]=j;
id[i][j]=cnt;
if(islower(ch)) s[ch-'a']=cnt;
else if(isupper(ch)) t[ch-'A']=cnt;
cnt++;
}
} for(int i=0;i<cnt;i++)
{
deg[i]=0;
for(int dir=0;dir<5;dir++)
{
int nx=x[i]+dx[dir];
int ny=y[i]+dy[dir];
if(maze[nx][ny]!='#')
G[i][deg[i]++]=id[nx][ny];
}
} if(n<=2) deg[cnt]=1,G[cnt][0]=cnt,s[2]=t[2]=cnt++;
if(n<=1) deg[cnt]=1,G[cnt][0]=cnt,s[1]=t[1]=cnt++;
printf("%d\n",solve());
}
return 0;
}

【UVa】1601 The Morning after Halloween(双向bfs)的更多相关文章

  1. UVA - 1601 The Morning after Halloween (双向BFS&单向BFS)

    题目: w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...

  2. UVA - 1601 The Morning after Halloween (BFS/双向BFS/A*)

    题目链接 挺有意思但是代码巨恶心的一道最短路搜索题. 因为图中的结点太多,应当首先考虑把隐式图转化成显式图,即对地图中可以相互连通的点之间连边,建立一个新图(由于每步不需要每个鬼都移动,所以每个点需要 ...

  3. UVA 1601 The Morning after Halloween

    题意: 给出一个最大为16×16的迷宫图和至多3个ghost的起始位置和目标位置,求最少经过几轮移动可以使三个ghost都到达目标位置.每轮移动中,每个ghost可以走一步,也可以原地不动,需要注意的 ...

  4. UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)

    题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...

  5. UVA 1601 双向BFS

    但是我们还不是很清楚每一次的状态怎么储存?我们可以用一个结构体,将每次的位置存起来,但是这个程序中用了一个更好的储存方法:我们知道最大的格数是16*16个,也就是256个,那么我们转换为二进制表示就是 ...

  6. <<操作,&0xff以及|的巧妙运用(以POJ3523---The Morning after Halloween(UVa 1601)为例)

    <<表示左移,如a<<1表示将a的二进制左移一位,加一个0,&0xff表示取最后8个字节,如a&0xff表示取a表示的二进制中最后8个数字组成一个新的二进制数, ...

  7. UVA1601-The Morning after Halloween(双向BFS)

    Problem UVA1601-The Morning after Halloween Accept: 289 Submit: 3136 Time Limit: 12000 mSec  Problem ...

  8. UVA-1601 The Morning after Halloween(BFS或双向BFS)

    题目大意:在一张图中,以最少的步数将a,b,c移到对应的A,B,C上去.其中,每个2x2的方格都有障碍并且不能两个小写字母同时占据一个格子. 题目分析:为避免超时,先将图中所有能联通的空格建起一张图, ...

  9. UVA - 11624 Fire! 双向BFS追击问题

    Fire! Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of ...

随机推荐

  1. vue.js 源代码学习笔记 ----- core lifecycle

    /* @flow */ import config from '../config' import Watcher from '../observer/watcher' import { mark, ...

  2. 将EasyRTMP_RTSP移植到Android平台实现的RTSP拉流转推RTMP直播流功能

    本文转自EasyDarwin开源团队成员Kim的博客:http://blog.csdn.net/jinlong0603/article/details/73253044 前言 安防互联网化的需求已经越 ...

  3. HAWQ + MADlib 玩转数据挖掘之(五)——奇异值分解实现推荐算法

    一.奇异值分解简介 奇异值分解简称SVD(singular value decomposition),可以理解为:将一个比较复杂的矩阵用更小更简单的三个子矩阵的相乘来表示,这三个小矩阵描述了大矩阵重要 ...

  4. BeautifulSoup的安装和使用

    Python用做数据处理还是相当不错的,如果你想要做爬虫,python是很好的选择,它有很多已经写好的类包,只要调用,即可完成很多复杂的功能,此文中所有的功能都是基于BeautifulSoup这个包. ...

  5. 【剑指offer】n个骰子的点数,C++实现

    # 题目 # 思路 # 代码

  6. json中的dumps和loads

    常用有2个方法,也是最基本的使用方法: 1.dumps:把字典转成json字符串 进行post的请求的时候就要用json.dumps来进行装换,利用get方法就可以不用了. 2.loads:把json ...

  7. ubuntu下mysql安装提供外网访问

    修改配置文件 1. sudo apt-get install mysql-server #安装mysql服务器 2. sudo apt-get install  mysql-client #安装mys ...

  8. Java 输出文件通过 BufferedWriter.newline() 方法换行

    最近项目中需要导出文件,其实导出文件是一个挺简单的事情.但是却遇到了很奇怪的问题. 首先导出到文件需要用到 BufferedWriter.而换行则是通过 bw.newline() 方法,问题将出在 n ...

  9. Open Asset Import Library(assimp) vs2010编译

    Assimp(Open Asset Import Library)是一个开源的3D模型导入解析库, 可以处理很多种3D文件格式:Collada, Blend, Obj, X, 3DS, LWO, MD ...

  10. 重温CLR(十五) 托管堆和垃圾回收

    本章要讨论托管应用程序如何构造新对象,托管堆如何控制这些对象的生存期,以及如何回收这些对象的内存.简单地说,本章要解释clr中的垃圾回收期是如何工作的,还要解释相关的性能问题.另外,本章讨论了如何设计 ...