HDU 5094 Maze(迷宫搜索)

题目:Maze

题意:给定一个迷宫的信息,迷宫的最多是50*50的规模,然后有p种钥匙,每种钥匙能够开启对应的门。

x1, y1, x2, y2, g,表示(x1,y1)和(x2,y2)的之间的信息,题目保证(x1,y1)和(x2,y2)一定是相邻的,即上下左右这四种关系之一。g=0表示是墙壁,永远不能通过。g>0表示第g种门,只有当持有第g种钥匙时才能开门通过。

x, y, q,表示在(x,y)这个位置有第q种钥匙。

然后求从左上角(1,1)到达右下角(n,m)的最短时间,不能到达输出-1。

由于门最多10种,所以可以用状态压缩来表示已经获取的钥匙的信息。注意同一个位置可能有多种钥匙。

剩下就是广搜一下,标记好访问过的状态就行了。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n, m, p;
int door[51][51][4], map[51][51];
bool vis[51][51][1<<10];
int xl[4]={-1,1,0,0};
int yl[4]={0,0,-1,1};
int getd(int a, int b, int c, int d){
	if(a==c){
		if(b<d)	return 3;
		return 2;
	}
	else{
		if(a<c)	return 1;
		return 0;
	}
}
struct Node{
	int x, y, st, u;
	Node(){}
	Node(int x, int y, int st, int u):x(x),y(y),st(st),u(u){}
};
int solve(){
	if(n==1 && m==1)	return 0;
	queue<Node> Q;
	Q.push(Node(1,1,map[1][1],0));
	while(!Q.empty()){
		Node nd = Q.front(); Q.pop();
		if(vis[nd.x][nd.y][nd.st])	continue;
		vis[nd.x][nd.y][nd.st] = 1;
		for(int i=0; i<4; i++){
			int a = nd.x+xl[i];
			int b = nd.y+yl[i];
			if(a<1 || a>n || b<1 || b>m)	continue;
			if(!door[nd.x][nd.y][i])	continue;
			int st = nd.st;
			if(door[nd.x][nd.y][i]>0){
				int d = 1<<(door[nd.x][nd.y][i]-1);
				if(!(st&d))	continue;
			}
			if(a==n && b==m)	return nd.u+1;
			st |= map[a][b];
			if(!vis[a][b][st])	Q.push(Node(a,b,st,nd.u+1));
		}
	}
	return -1;
}
int main(){
	while(~scanf("%d %d %d", &n, &m, &p)){
		memset(door, -1, sizeof(door));
		memset(map, 0, sizeof(map));
		memset(vis, 0, sizeof(vis));
		int k;
		scanf("%d", &k);
		int a, b, c, d, e;
		while(k--){
			scanf("%d %d %d %d %d", &a, &b, &c, &d, &e);
			door[a][b][getd(a,b,c,d)] = e;
			door[c][d][getd(c,d,a,b)] = e;
		}
		scanf("%d", &k);
		while(k--){
			scanf("%d %d %d", &a, &b, &c);
			map[a][b] |= (1<<(c-1));
		}
		printf("%d\n", solve());
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值