[状态压缩 广搜BFS]Saving Tang Monk

2024-06-21 12:04
文章标签 bfs 压缩 状态 saving tang monk

本文主要是介绍[状态压缩 广搜BFS]Saving Tang Monk,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

描述

《Journey to the West》(also 《Monkey》) is one of the Four Great Classical Novels of Chinese literature. It was written by Wu Cheng'en during the Ming Dynasty. In this novel, Monkey King Sun Wukong, pig Zhu Bajie and Sha Wujing, escorted Tang Monk to India to get sacred Buddhism texts.

During the journey, Tang Monk was often captured by demons. Most of demons wanted to eat Tang Monk to achieve immortality, but some female demons just wanted to marry him because he was handsome. So, fighting demons and saving Monk Tang is the major job for Sun Wukong to do.

Once, Tang Monk was captured by the demon White Bones. White Bones lived in a palace and she cuffed Tang Monk in a room. Sun Wukong managed to get into the palace. But to rescue Tang Monk, Sun Wukong might need to get some keys and kill some snakes in his way.

The palace can be described as a matrix of characters. Each character stands for a room. In the matrix, 'K' represents the original position of Sun Wukong, 'T' represents the location of Tang Monk and 'S' stands for a room with a snake in it. Please note that there are only one 'K' and one 'T', and at most five snakes in the palace. And, '.' means a clear room as well '#' means a deadly room which Sun Wukong couldn't get in.

There may be some keys of different kinds scattered in the rooms, but there is at most one key in one room. There are at most 9 kinds of keys. A room with a key in it is represented by a digit(from '1' to '9'). For example, '1' means a room with a first kind key, '2' means a room with a second kind key, '3' means a room with a third kind key... etc. To save Tang Monk, Sun Wukong must get ALL kinds of keys(in other words, at least one key for each kind).

For each step, Sun Wukong could move to the adjacent rooms(except deadly rooms) in 4 directions(north,west,south and east), and each step took him one minute. If he entered a room in which a living snake stayed, he must kill the snake. Killing a snake also took one minute. If Sun Wukong entered a room where there is a key of kind N, Sun would get that key if and only if he had already got keys of kind 1,kind 2 ... and kind N-1. In other words, Sun Wukong must get a key of kind N before he could get a key of kind N+1 (N>=1). If Sun Wukong got all keys he needed and entered the room in which Tang Monk was cuffed, the rescue mission is completed. If Sun Wukong didn't get enough keys, he still could pass through Tang Monk's room. Since Sun Wukong was a impatient monkey, he wanted to save Tang Monk as quickly as possible. Please figure out the minimum time Sun Wukong needed to rescue Tang Monk.

输入

There are several test cases.

For each case, the first line includes two integers N and M(0 < N <= 100, 0 <= M <= 9), meaning that the palace is a N * N matrix and Sun Wukong needed M kinds of keys(kind 1, kind 2, ... kind M).

Then the N*N matrix follows.

The input ends with N = 0 and M = 0.

输出

For each test case, print the minimum time (in minute) Sun Wokong needed to save Tang Monk. If it's impossible for Sun Wokong to complete the mission, print "impossible".

样例输入

3 1
K.S
##1
1#T
3 1
K#T
.S#
1#.
3 2
K#T
.S.
21.
0 0

样例输出

5
impossible
8
解题分析

这道题可以算是广搜的天花板之一了,不仅需要状态压缩的策略,还需要使用一些形如priority_queue的数据结构来辅助,而且关于已访问过的标记,包括拿到的钥匙,杀死的蛇等等细节都很值得推敲。以及说,我们可以用一个数组来存储我们钥匙的状态,并且我们考虑的是其二进制的表达式。首先,正常地读入数据,注意,由于我们可能有很多组数组,所以每次的while循环的开始,我们应该重置我们需要重置的一些变量,比如说访问数组归0,蛇计数数组归0,答案ans的重置。接着读入整个迷宫,需要注意的是,我们需要孙悟空的初始位置,以及我们读入蛇的时候,把这条蛇的信息放入一个数组里面,并且标记它的位置。对于我们广搜时放入priority_queue的节点的话,我们希望它有我们的位置,杀死蛇的情况,钥匙情况以及我们的步数,位置坐标和步数是很基本的。注意,我们每次的广搜,只走一步!所以我们在一次的循环里不能直接更改我们当前读取的队列开头的元素的信息,所以另设变量去处理是一个很好的选择。一共三种情况,要么是钥匙,要么是蛇,要么就是唐僧,分情况,利用位操作去判断,去处理,用&运算取出某一位,用|运算去把某一位设置为1,诸如此类,这般这般。最后输出答案即可。

代码演示
#include <iostream>
#include <cmath>
//#include <iomanip>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <bitset>
#include <queue>
#include <stack>
#include <cstdlib>
#define INF (1<<30)
using namespace std;int N,M;
char maze[105][105];
bitset<513> vis_keys[105][105];
bitset<33> vis_snakes[105][105];
int ans=INF;
int Kx,Ky,k;
int keys[]={0,1,3,7,15,31,63,127,255,511};
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};struct Node{int x,y,snakes,keys,step;bool operator<(const Node& o) const{return step>o.step;}
};struct snake{int x,y;
} snakes[5];
Node tmp;int bfs(){priority_queue<Node> q;q.push({Kx,Ky,0,0,0});while(q.size()){tmp=q.top();q.pop();for(int i=0;i<4;i++){int x0=tmp.x+dx[i];int y0=tmp.y+dy[i];if(x0<0 || y0<0 || x0>=N || y0>=N || maze[x0][y0]=='#') continue;if(vis_keys[x0][y0][tmp.keys]==1 && vis_snakes[x0][y0][tmp.snakes]==1) continue;int nsnakes=tmp.snakes,nkeys=tmp.keys,nstep=tmp.step+1;if(isdigit(maze[x0][y0])){int m=maze[x0][y0]-'0';if(m==1 || (nkeys>>(m-2)) & 1){nkeys |= (1<<(m-1));}}else if(maze[x0][y0]=='S'){int index=0;for(int i=0;i<k;i++){if(snakes[i].x==x0 && snakes[i].y==y0){index=i;break;}}if(!((nsnakes>>index) & 1)){nsnakes |=(1<<index);nstep +=1;}}else if(maze[x0][y0]=='T' && nkeys==keys[M]){return nstep;}q.push({x0,y0,nsnakes,nkeys,nstep});vis_keys[x0][y0][nkeys]=1;vis_snakes[x0][y0][nsnakes]=1;}}return -1;
}int main(){while(scanf("%d%d",&N,&M)!=EOF){if(N==0 && M==0) break;memset(vis_keys,0,sizeof(vis_keys));memset(vis_snakes,0,sizeof(vis_snakes));k=0;ans=1<<30;for(int i=0;i<N;i++)for(int j=0;j<N;j++){scanf(" %c",&maze[i][j]);if(maze[i][j]=='K'){Kx=i;Ky=j;}else if(maze[i][j]=='S'){snakes[k++]={i,j};}}ans=bfs();if(ans==-1){printf("impossible\n");}else{printf("%d\n",ans);}}return 0;
}

这篇关于[状态压缩 广搜BFS]Saving Tang Monk的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1081173

相关文章

SpringSecurity JWT基于令牌的无状态认证实现

《SpringSecurityJWT基于令牌的无状态认证实现》SpringSecurity中实现基于JWT的无状态认证是一种常见的做法,本文就来介绍一下SpringSecurityJWT基于令牌的无... 目录引言一、JWT基本原理与结构二、Spring Security JWT依赖配置三、JWT令牌生成与

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

关于WebSocket协议状态码解析

《关于WebSocket协议状态码解析》:本文主要介绍关于WebSocket协议状态码的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录WebSocket协议状态码解析1. 引言2. WebSocket协议状态码概述3. WebSocket协议状态码详解3

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML

Python实现将MySQL中所有表的数据都导出为CSV文件并压缩

《Python实现将MySQL中所有表的数据都导出为CSV文件并压缩》这篇文章主要为大家详细介绍了如何使用Python将MySQL数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到... python将mysql数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到另一个

Flutter监听当前页面可见与隐藏状态的代码详解

《Flutter监听当前页面可见与隐藏状态的代码详解》文章介绍了如何在Flutter中使用路由观察者来监听应用进入前台或后台状态以及页面的显示和隐藏,并通过代码示例讲解的非常详细,需要的朋友可以参考下... flutter 可以监听 app 进入前台还是后台状态,也可以监听当http://www.cppcn

MySQL 中的服务器配置和状态详解(MySQL Server Configuration and Status)

《MySQL中的服务器配置和状态详解(MySQLServerConfigurationandStatus)》MySQL服务器配置和状态设置包括服务器选项、系统变量和状态变量三个方面,可以通过... 目录mysql 之服务器配置和状态1 MySQL 架构和性能优化1.1 服务器配置和状态1.1.1 服务器选项

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

Python利用PIL进行图片压缩

《Python利用PIL进行图片压缩》有时在发送一些文件如PPT、Word时,由于文件中的图片太大,导致文件也太大,无法发送,所以本文为大家介绍了Python中图片压缩的方法,需要的可以参考下... 有时在发送一些文件如PPT、Word时,由于文件中的图片太大,导致文件也太大,无法发送,所有可以对文件中的图