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

本文介绍了一种基于广度优先搜索(BFS)的迷宫寻路算法,通过使用状态表示和时间限制,解决了迷宫中寻找从起点到终点路径的问题,并考虑了钥匙和门等特殊元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
struct node{
	int x,y;
	int state;//用1024内的数表示状态 
	int tim;
};
char map[30][30];
int v[21][21][1500];
int dis[4][2]={-1,0,0,-1,1,0,0,1};
int two[11]={1,2,4,8,16,32,64,128,256,512,1024};//用two数组来记录2的次方 反复调用函数会增加时间 
int n,m,t,si,sj,di,dj;
int change(int state,int key)//收到钥匙后改变状态 
{
	return(state|two[key]);
}
int op(int state,int door)//判断有没有门对应的钥匙 
{
	if((state&two[door])>0)
		return 1;
	else
		return 0;
}
void bfs()
{
	queue <node> q;
	struct node start,now,nex,fin;
	int key,door;
	start.x=si; start.y=sj; start.state=0; start.tim=0;
	q.push(start);
	while(!q.empty())
	{
		now=q.front();
		if(now.x==di&&now.y==dj)
			{
				printf("%d\n",now.tim);
				return;
			}
		q.pop();
		for(int i=0;i<=3;i++)
		{
			nex.x=now.x+dis[i][0];
			nex.y=now.y+dis[i][1];
			nex.tim=now.tim+1;
			key=map[nex.x][nex.y]-'a'; 
			door=map[nex.x][nex.y]-'A';//用来判断是门还是钥匙 
			if(key<10&&key>=0)
				nex.state=change(now.state,key);
			else
				nex.state=now.state;
			if(door>=0&&door<10&&nex.tim<t)
				{	if(op(nex.state,door)&&v[nex.x][nex.y][nex.state]==0)
					{
						if(nex.tim%t==0&&(nex.x!=di||nex.y!=dj))
							{nex.x=si;nex.y=sj;}
						q.push(nex);
						v[nex.x][nex.y][nex.state]=1;
					}
				}
			else if(map[nex.x][nex.y]!='*'&&v[nex.x][nex.y][nex.state]==0&&nex.tim<t)
				{
					q.push(nex);
					v[nex.x][nex.y][nex.state]=1;
				}
		}
	}
	printf("-1\n");
}
int main()
{
	int i,j;
	while(~scanf("%d%d%d",&n,&m,&t))
	{
		memset(v,0,sizeof(v));
		memset(map,'*',sizeof(map));
		for(i=1;i<=n;i++)
			scanf("%s",map[i]+1);
		for(i=1;i<=n;i++)
			map[i][m+1]='*';//初始化边界 个人喜欢在外围一堵墙 
		for(i=1;i<=n;i++)
			for(j=1;j<=m;j++)
				{
					if(map[i][j]=='@')
						{
							si=i;
							sj=j;
						}
					if(map[i][j]=='^')
						{
							di=i;
							dj=j;
						}
				}
		if(abs(si-di)+abs(sj-dj)>=t) {printf("-1\n");continue;}//到达不了的剪掉 
		bfs();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值