题意:给定一个n*m的矩阵,里面有门,有钥匙,有出口,问你逃出去的最短路径是多少。

析:这很明显是一个BFS,但是,里面又有其他的东西,所以我们考虑状态压缩,定义三维BFS,最后一维表示拿到钥匙的状态,然后再BFS,就简单了。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 100 + 5;
const int mod = 1e9 + 7;
const int dr[] = {0, 1, 0, -1};
const int dc[] = {1, 0, -1, 0};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
struct Node{
int x, y, d, state;
Node() { }
Node(int xx, int yy, int dd, int k) : x(xx), y(yy), d(dd), state(k) { }
};
char s[maxn][maxn];
bool vis[maxn][maxn][20];
map<char, int> key, door; void bfs(int x, int y){
queue<Node> q;
memset(vis, 0, sizeof vis);
q.push(Node(x, y, 0, 0));
vis[x][y][0] = true; while(!q.empty()){
Node u = q.front(); q.pop();
for(int i = 0; i < 4; ++i){
int x = u.x + dr[i];
int y = u.y + dc[i];
int d = u.d + 1;
if(!is_in(x, y)) continue;
if(s[x][y] == 'X'){
printf("Escape possible in %d steps.\n", d);
return ;
}
if(s[x][y] == '#') continue;
int state;
if(islower(s[x][y])) state = u.state | (1 << key[s[x][y]]);
else if(isupper(s[x][y])){
if(u.state & (1<<door[s[x][y]])) state = u.state;
else continue;
}
else if(s[x][y] == '.' || s[x][y] == '*') state = u.state;
if(!vis[x][y][state]){
vis[x][y][state] = true;
q.push(Node(x, y, d, state));
}
}
}
printf("The poor student is trapped!\n");
} int main(){
key['b'] = 1; door['B'] = 1;
key['y'] = 2; door['Y'] = 2;
key['r'] = 3; door['R'] = 3;
key['g'] = 0; door['G'] = 0;
while(scanf("%d %d", &n, &m) == 2){
if(!n && !m) break;
for(int i = 0; i < n; ++i) scanf("%s", s+i);
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
if(s[i][j] == '*') { bfs(i, j); break; }
}
return 0;
}

HDU 1885 Key Task (BFS + 状态压缩)的更多相关文章

  1. hdu 1885 Key Task(bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1885 再贴一个链接http://blog.csdn.net/u013081425/article/details ...

  2. HDU 1885 Key Task (带门和钥匙的迷宫搜索 bfs+二进制压缩)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1885 Key Task Time Limit: 3000/1000 MS (Java/Others)  ...

  3. hdu 1885 Key Task

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1885 Key Task Description The Czech Technical Univers ...

  4. HDU 1885 Key Task(三维BFS)

    题目链接 题意 : 出口不止一个,一共有四种颜色不同的门由大写字母表示,而钥匙则是对应的小写字母,当你走到门前边的位置时,如果你已经走过相应的钥匙的位置这个门就可以走,只要获得一把钥匙就可以开所有同颜 ...

  5. HDU 1885 Key Task 国家压缩+搜索

    点击打开链接 Key Task Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. hdu 4634 Swipe Bo bfs+状态压缩

    题目链接 状态压缩记录当前拿到了哪些钥匙, 然后暴力搜索. 搞了好几个小时, 一开始也不知道哪里错了, 最后A了也不知道一开始哪里有问题. #include <iostream> #inc ...

  7. hdu 1885 Key Task(bfs+状态压缩)

    Problem Description The Czech Technical University years of its existence . Some of the university b ...

  8. hdu 1885 Key Task (三维bfs)

    题目 之前比赛的一个题, 当时是崔老师做的,今天我自己做了一下.... 还要注意用bfs的时候  有时候并不是最先到达的就是答案,比如HDU 3442 这道题是要求最小的消耗血量伤害,但是并不是最先到 ...

  9. hdu 1885 Key Task(bfs+位运算)

    题意:矩阵中'#'表示墙,'.'表示通路,要求从起点'*'到达终点'X',途中可能遇到一些门(大写字母),要想经过,必须有对应的钥匙(小写字母).问能否完成,若能,花费的时间是多少. 分析:同hdu ...

随机推荐

  1. ArchLinux KDE安装中文输入法

    From: http://www.linuxdiyf.com/viewarticle.php?id=53375 1.安装中文输入法#pacman -S scim-pinyin #拼音输入法#pacma ...

  2. EventBus的一个bug??

    今天遇到了一个很奇怪的问题,activity A打开B,A和B中都注册了eventbus,都会接一个list的参数,当然两个list的参数不同,居然会报一个异常,A中List的参数会变成B的类型,错误 ...

  3. 一个CString的实现 拷贝构造函数的应用

    class CString { public: CString (char* s); CString(); ~CString(); private: char *str; int len; stati ...

  4. Mybatis保存数据时事务问题

    今天不小心在sqlplus中用for update ,然后事务没提交,结果在项目中一直保存不进去数据,找了很久发现是sqlplus中的事务没提交,哎,这种问题真得避免啊,一定要细心啊!

  5. 日志分析工具ELK配置详解

    日志分析工具ELK配置详解 一.ELK介绍 1.1 elasticsearch 1.1.1 elasticsearch介绍 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分 ...

  6. ps 进程查看器

    命令参数 a 显示所有进程 -a 显示同一终端下的所有程序 -A 显示所有进程 c 显示进程的真实名称 -N 反向选择 -e 等于"-A" e 显示环境变量 f 显示程序间的关系 ...

  7. 《深入理解Nginx》阅读与实践(二):配置项的使用

    前文链接:<深入理解Nginx>阅读与实践(一):Nginx安装配置与HelloWorld HelloWorld的完成意味着已经踏入了nginx的大门,虽然很振奋人心,但在编写中仍有很多疑 ...

  8. Linux课程实践一:Linux基础实践(基础操作)

    一.软件源维护 1. 基本操作 (1)查看源列表 sudo vim /etc/apt/sources.list deb:二进制软件安装包 deb-src:源码包 (2)备份软件源列表 sudo cp ...

  9. 超链接的那些事(二): 属性href

    a标签的属性之一 href 1. 定义 href 属性用于指定超链接目标的 URL. 2. 用法     ①. 锚点 同一页面添加锚点 (1)<a href="#test"& ...

  10. RHEL7网络管理之nmcli

    在RHEL7中默认使用NetworkManager 守护进程来监控和管理网络设置.nmcli是命令行的管理NetworkManager的工具,会自动把配置写到/etc/sysconfig/networ ...