其他分享
首页 > 其他分享> > 【题解】HDU5094 Maze

【题解】HDU5094 Maze

作者:互联网

题目描述:

这个故事发生在“星际迷航”的背景下。

“星际争霸”的副队长史波克落入克林贡的诡计中,被关押在他们的母亲星球Qo'noS上。

企业的上尉詹姆斯·T·柯克(James T. Kirk)不得不乘宇宙飞船去救他的副手。幸运的是,他偷走了史波克所在的迷宫地图。

迷宫是一个矩形,它有n行垂直和m列水平,换句话说,它被分为n * m个位置。有序对(行号,列号)表示迷宫中的位置。柯克从当前位置移动到下一个花费1秒。而且他只有在以下情况下才能移动到下一个位置:

下一个位置与当前柯克的位置相邻(上下或左右)(4个方向)
开着的门是可以通行的,但锁着的门不是。
柯克不能通过一堵墙

有几种门是默认锁定的。钥匙只能打开相同类型的门。柯克必须在打开相应的门之前拿到钥匙,这样很浪费时间。

柯克的初始位置是(1,1),而史波克位于(n,m)的位置。你的任务是帮助Kirk尽快找到史波克。
\(1 \le n,m \le 50\) 钥匙种类小于等于 \(10\)

题目分析:

看到这么少的钥匙自然会想到状压 \(DP\),但是我们会发现我们的转移并不是十分简单的,他是通过遍历整张图来转移的。那么我们如果记录一个数组 \(dp[i][j][S]\) 代表到达 \((i,j)\) 这个点,拿到钥匙的情况为 \(S\) 的话是十分麻烦的,而且也没有必要。那么我们就在遍历图也就是 \(\text{BFS}\) 的时候记下当前点是什么,拿到钥匙的情况以及走到这里花了几秒。我们的状态压缩只是指的将状态压缩成二进制,而不是指的必须使用类似 \(DP\) 的方法转移。

代码详解:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
struct node{
	int x,y,key,cost; 
	node(){}
	node(int _x,int _y,int _key,int _cost){
		x = _x,y=_y,key = _key,cost = _cost;
	}
};
bool vis[55][55][1<<11];
int n,m,key[55][55],wall[55][55][55][55];
int dx[7] = {0,1,-1,0,0};
int dy[7] = {0,0,0,1,-1};
void bfs(){
	queue<node> q;
	vis[1][1][key[1][1]] = true;
	q.push(node(1,1,key[1][1],0));
	while(!q.empty()){
		node now = q.front();q.pop();
		if(now.x == n && now.y == m){
			cout<<now.cost<<endl;
			return;
		}
		for(int i=1; i<=4; i++){
			int fx = dx[i] + now.x,fy = dy[i] + now.y;
			if(!(fx >= 1 &&  fx <= n && fy >= 1 && fy <= m))	continue;
			int door = wall[now.x][now.y][fx][fy];
			int key1 = now.key;
			int key2 = key1 | key[fx][fy];
			if(!vis[fx][fy][key2] && (door == -1 || (1<<(door-1) & key1))){
				q.push(node(fx,fy,key2,now.cost + 1));
				vis[fx][fy][key2] = true;
			}
		}
	} 
	cout<<-1<<endl;
}
int main(){
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	int p;
	while(cin>>n>>m>>p){
		memset(wall,-1,sizeof(wall));
		memset(key,0,sizeof(key));
		memset(vis,false,sizeof(vis));
		int k;
		cin>>k;
		for(int i=1; i<=k; i++){
			int x1,y1,x2,y2,g;
			cin>>x1>>y1>>x2>>y2>>g;
			wall[x1][y1][x2][y2] = wall[x2][y2][x1][y1] = g;
		}
		int s;
		cin>>s;
		for(int i=1; i<=s; i++){
			int x,y,z;
			cin>>x>>y>>z;
			key[x][y] |= (1<<(z-1));
		}
		bfs();
	}
	return 0;
} 

标签:node,柯克,int,题解,vis,cost,key,Maze,HDU5094
来源: https://www.cnblogs.com/linyihdfj/p/16472434.html