ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】HDU5094 Maze

2022-07-13 07:00:07  阅读:115  来源: 互联网

标签:node 柯克 int 题解 vis cost key Maze HDU5094


题目描述:

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

“星际争霸”的副队长史波克落入克林贡的诡计中,被关押在他们的母亲星球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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有