hdu 1429 胜利大逃亡(续)【广度优先搜索+状态压缩】

胜利大逃亡(续)

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 5411    Accepted Submission(s): 1863

Problem Description

Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……

这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。

Input

每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t>0)。接下来的n行m列为地牢的地图,其中包括:

. 代表路

* 代表墙

@ 代表Ignatius的起始位置

^ 代表地牢的出口

A-J 代表带锁的门,对应的钥匙分别为a-j

a-j 代表钥匙,对应的门分别为A-J

每组测试数据之间有一个空行。

Output

针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。

Sample Input

4 5 17
@A.B.
a*.*.
*..*^
c..b*

4 5 16
@A.B.
a*.*.
*..*^
c..b*

Sample Output

16
-1

分析:本题最多有10把钥匙,在广搜过程中,每一步要判断次当前节点是否为钥匙,那一把钥匙,一次每一个节点状态很多,

很难标记,因此可以用状态压缩,每个有两种状态,有钥匙或没钥匙,是那把钥匙,共2的10次方种情况,所以可以标记数组

visit【M】【N】【2^10】,若当前节点是钥匙,则记录已有次要是标号,若当前节点为门,则判断是否有此门钥匙,可用问运算

解决。

代码示例:

#include<stdio.h>

#include<string.h>

#include<algorithm>

#include<iostream>

#include<queue>

using namespace std;

typedef struct

{

int x,y;

int key;

int step;

}node;

int n,m,sx,sy,gx,gy,k;

int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};

char map[30][30];

int visit[30][30][1025];

bool judge(int x,int y)

{

if(x<1||x>m||y<1||y>n)

return true;

return false;

}

int bfs()

{

int x,y,z,value;

node fir,nex;

queue<node>Q;

for(int i=1;i<=m;i++)

for(int j=1;j<=n;j++)

for(int l=0;l<1025;l++)

visit[i][j][l]=0;

fir.x=sx,fir.y=sy,fir.step=0;

fir.key=0;

visit[sx][sy][0]=1;

Q.push(fir);

while(!Q.empty())

{

fir=Q.front();

Q.pop();

if(fir.x==gx&&fir.y==gy&&fir.step<k)

return fir.step;

for(int i=0;i<4;i++)

{

nex=fir;

x=fir.x+dir[i][0];

y=fir.y+dir[i][1];

z=fir.key;

if(judge(x,y)||visit[x][y][z]||map[x][y]==‘*‘)

continue;

if(map[x][y]>=‘A‘&&map[x][y]<=‘J‘)

{

value=map[x][y]-‘A‘;

if((z&(1<<value))!=(1<<value))

continue;

}

if(map[x][y]>=‘a‘&&map[x][y]<=‘j‘)

{

value=map[x][y]-‘a‘;

z=z|(1<<value);

}

nex.x=x,nex.y=y,nex.key=z;

nex.step++;

visit[x][y][z]=1;

Q.push(nex);

}

}

return -1;

}

int main()

{

while(~scanf("%d%d%d",&m,&n,&k))

{

for(int i=1;i<=m;i++)

for(int j=1;j<=n;j++)

{

cin>>map[i][j];

if(map[i][j]==‘@‘)

sx=i,sy=j;

if(map[i][j]==‘^‘)

gx=i,gy=j;

}

printf("%d\n",bfs());

}

return 0;

时间: 2024-08-24 02:09:54

hdu 1429 胜利大逃亡(续)【广度优先搜索+状态压缩】的相关文章

HDU 1429 胜利大逃亡(续)(bfs+状态压缩,很经典)

传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10648    Accepted Submission(s): 3860 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王

HDU 1429胜利大逃亡(续) (bfs+状态压缩)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6469 Accepted Submission(s): 2243 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)-- 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥

hdoj 1429 胜利大逃亡(续) 【BFS+状态压缩】

题目:hdoj 1429 胜利大逃亡(续) 相同题目: 题意:中文的,自己看 分析:题目是求最少的逃亡时间,确定用BFS 这个题目的难点在于有几个锁对于几把钥匙,唯一的对应关系,不能用直接的标记法,因为一个图可能需要搜索多次. 仔细分析的话会发现,图的搜索次数是和钥匙的出现次数相关,那么我们可以用二进制的0 和 1 来表示第几把钥匙出现过没有,所以我们可以用状态压缩来标记那个钥匙出现过,然后用三维标记,第三维表示出现几个钥匙了的情况下图的点的搜索情况.其他就和简单的一样. AC代码: #incl

hdu 1429 胜利大逃亡(续)(BFS+位压缩)

#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <string> #include <ma

hdu 1429 胜利大逃亡(续) 搜索+状态压缩,,不错的题。

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5860    Accepted Submission(s): 2046 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)-- 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了

HDU 1429 胜利大逃亡(续)(bfs)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6270    Accepted Submission(s): 2177 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)-- 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了

hdu 1429 胜利大逃亡(续)(bfs+位压缩)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7346    Accepted Submission(s): 2546 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)…… 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

hdu.1429.胜利大逃亡(续)(bfs + 0101011110)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6070    Accepted Submission(s): 2096 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

HDU 1429--胜利大逃亡(续)【BFS &amp;&amp; 状态压缩】

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6656    Accepted Submission(s): 2315 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)-- 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了