题目

题目

 


 

分析

双向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. postfix基于客户端的访问控制

    1.基于客户端的访问控制概览 postfix内置了多种反垃圾邮件的机制,其中就包括“客户端”发送邮件限制.客户端判别机制可以设定一系列客户信息的判别条件: smtpd_client_restricti ...

  2. 海思arm平台AAC音频转码cpu占用高、效率低的问题解决

    问题背景 目前市面上的大部分IPC摄像机音频输出基本都是G711.G726编码格式,而在类似于<基于EasyNVR实现RTSP/Onvif监控摄像头Web无插件化直播监控>这种业务中,都是 ...

  3. Xcode9 新功能

    翻译: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/WhatsNewXcod ...

  4. Vue学习笔记 ——computed VS methods

    对于最终的结果,两种方式确实是相同的.然而,不同的是计算属性是基于它们的依赖进行缓存的.计算属性只有在它的相关依赖发生改变时才会重新求值.这就意味着只要 message 还没有发生改变,多次访问 re ...

  5. UICollectionView 数据库元素分组 多种section分开显示

    第一遍 复杂方法 : 数据库查询一个表中userID 然后进行分类 中间去重 获得ID个数  放到section 中  显示 #pragma mark -  查询不同的ID 各数  - (void)c ...

  6. js之简易计算器

    <!DOCTYPE html PUBLIC "-//W3C//Dli XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 【剑指offer】顺时针打印矩阵,C++实现

    原创文章,转载请注明出处! 博客文章索引地址 1.题目 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵,则依次打印出数字1,2,3,4,8,12,16,15,14 ...

  8. ZOJ3551Bloodsucker (数学期望)

    In 0th day, there are n-1 people and 1 bloodsucker. Every day, two and only two of them meet. Nothin ...

  9. BZOJ1597土地购买 【斜率优化DP】

    BZOJ1597土地购买 [斜率优化DP] Description 农夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足( ...

  10. IOS UIView 放大缩小

    /创建缩小了的视图myWeiBoImageVC = [[UIViewController alloc] init];myWeiBoImageVC.view.clipsToBounds = YES;my ...