题目

题目

 


 

分析

双向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. Ubuntu 中sendmail 的安装、配置与发送邮件的具体实现

    一.安装 ubuntu中sendmail函数可以很方便的发送邮件,ubuntu sendmail先要安装两个包. 必需安装的两个包: 代码  sudo apt-get install sendmail ...

  2. HDU 3345

    http://acm.hdu.edu.cn/showproblem.php?pid=3345 最近重写usaco压力好大,每天写的都想吐.. 水一道bfs 注意的是开始旁边有敌人可以随便走,但是一旦开 ...

  3. IOS开发 CocoaPods 使用 pod Install 出现 Updating local specs repositories

    pod install 换成pod install --verbose --no-repo-update这个命令,前面的命令被墙了

  4. 【排序】快速排序,C++实现

    原创博文,转载请注明出处! 本文代码的github地址 # 基本思想 ”快速排序“是对”冒泡排序“的改进. 基本原理:基于分治法,在待排线性表中取一个元素pivot作为枢轴值,通过一趟排序将待排线性表 ...

  5. Git学习的网址

    http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 https://github.co ...

  6. JavaScript:逻辑操作符“==”与“===”的区别

    Summary JavaScript中,逻辑操作符“===”会先检查操作数的数据类型,对不同的数据类型会返回false. 而“==”对不同类型的操作数进行比较时,会进行类型转换后再比较. Descri ...

  7. NOI2001 食物链【扩展域并查集】*

    NOI2001 食物链 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的 ...

  8. BZOJ3747 POI2015 Kinoman 【线段树】*

    BZOJ3747 POI2015 Kinoman Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[ ...

  9. 【模板】FFT

    FFT模板 安利一下前辈的博客,写的真的好点击这里:从多项式乘法到快速傅里叶变换 #include<bits/stdc++.h> using namespace std; const in ...

  10. BZOJ3196 Tyvj1730 二逼平衡树 【树套树】 【线段树套treap】

    BZOJ3196 Tyvj1730 二逼平衡树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名 ...