hdu_1429_胜利大逃亡(续)(BFS状压)

7 篇文章 0 订阅

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1429

题意:迷宫的加强版,迷宫里有钥匙和门,问在指定的时间下能否逃出

题解:用二进制位来记录是否有该门的钥匙,然后上BFS

#include<cstdio>
#include<queue>
#include<cstring>
#define FFC(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n,m,t,j,sx,sy,d[][2]={1,0,-1,0,0,1,0,-1};bool v[22][22][1025];char g[22][22];
struct dt{int x,y,tm,key;};//用二进制位来压缩状态
bool check(int x,int y){if(x<1||x>n||y<1||y>m||g[x][y]=='*')return 0;return 1;}
int fuck(){
	dt s,o;s.x=sx,s.y=sy,s.tm=0,s.key=0;
	memset(v,0,sizeof(v));
	queue<dt>Q;Q.push(s);
	while(!Q.empty()){
		o=Q.front();Q.pop();
		if(g[o.x][o.y]=='^'&&o.tm<t)return o.tm;
		if(o.tm>t)continue;
		for(int i=0;i<4;i++){
			int xx=o.x+d[i][0],yy=o.y+d[i][1],kkey=o.key;
			if(!check(xx,yy))continue;//检测边界
			if(g[o.x][o.y]>='A'&&g[o.x][o.y]<='Z'&&!((o.key>>(g[o.x][o.y]-'A'))&1))continue;//检测能否打开门
			if(g[xx][yy]>='a'&&g[xx][yy]<='z')kkey|=(1<<(g[xx][yy]-'a'));//拣钥匙
			if(v[xx][yy][kkey])continue;//判断在有这些钥匙的情况下是否搜过该点
			s.x=xx,s.y=yy,s.tm=o.tm+1,s.key=kkey,v[xx][yy][kkey]=1;
			Q.push(s);
		}
	}
	return -1;
}
int main(){
	while(~scanf("%d%d%d",&n,&m,&t)){
		FFC(i,1,n){
			getchar();
			for(j=1;j<=m;j++){scanf("%c",&g[i][j]);if(g[i][j]=='@')sx=i,sy=j;}
		}
		printf("%d\n",fuck());
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值