HDU 1429 胜利大逃亡(续) (bfs+状态压缩)
2016-08-23 14:02
375 查看
胜利大逃亡(续)
题目链接:
http://acm.hust.edu.cn/vjudge/contest/71151#problem/DDescription
Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。
Input
每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t > 0)。接下来的n行m列为地牢的地图,其中包括:. 代表路 * 代表墙 @ 代表Ignatius的起始位置 ^ 代表地牢的出口 A-J 代表带锁的门,对应的钥匙分别为a-j a-j 代表钥匙,对应的门分别为A-J
每组测试数据之间有一个空行。
Output
针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。Sample Input
4 5 17 @A.B. a*.*. *..*^ c..b* 4 5 16 @A.B. a*.*. *..*^ c..b*
Sample Output
16 -1
题意:
在n*m的地图上,有10种类型的门及其对应钥匙,求最少的时间从起点到达终点,T-1内不能到达则输出-1.题解:
类似魔塔的搜索题,这里用bfs来搜最小步数即可. 用状态压缩处理每个位置拿到的钥匙状态.判重:除了点坐标外,需要额外记录达到当前点的钥匙状态. (因为有些位置可能重复到达).
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #include <set> #include <stack> #include <vector> #include <list> #define LL long long #define eps 1e-8 #define maxn 25 #define mod 100000007 #define inf 0x3f3f3f3f #define mid(a,b) ((a+b)>>1) #define IN freopen("in.txt","r",stdin); using namespace std; int n, m, T; char mp[maxn][maxn]; bool vis[maxn][maxn][1<<10]; bool is_ok(int x, int y) { return x>=0 && y>=0 && x<n && y<m; } struct node { int x,y; int step, key; }; int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}}; int bfs(int sx, int sy) { queue<node> q; while(!q.empty()) q.pop(); node cur, next; cur.x = sx, cur.y = sy, cur.step = 0, cur.key = 0; q.push(cur); vis[sx][sy][0] = 1; while(!q.empty()) { cur = q.front(); q.pop(); for(int i=0; i<4; i++) { int xx = cur.x + dir[i][0]; int yy = cur.y + dir[i][1]; if(!is_ok(xx,yy) || mp[xx][yy]=='*') continue; next.x = xx, next.y = yy, next.step = cur.step + 1; next.key = cur.key; if(next.step == T) continue; if(mp[xx][yy] == '^') return next.step; if(mp[xx][yy]>='a' && mp[xx][yy]<='z') { next.key |= (1 << (mp[xx][yy]-'a')); } if(mp[xx][yy]>='A' && mp[xx][yy]<='Z') { if((next.key & (1 << (mp[xx][yy]-'A'))) == 0) continue; } if(vis[next.x][next.y][next.key]) continue; vis[next.x][next.y][next.key] = 1; q.push(next); } } return -1; } int main(int argc, char const *argv[]) { //IN; while(scanf("%d %d %d", &n,&m,&T) != EOF) { for(int i=0; i<n; i++) scanf("%s", mp[i]); int sx = -1, sy = -1; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) if(mp[i][j] == '@') { sx = i, sy = j; break; } if(sx != -1) break; } memset(vis, 0, sizeof(vis)); int ans = bfs(sx, sy); printf("%d\n", ans); } return 0; }
相关文章推荐
- 数据统一管理--企业决策分析之刚需
- 执行non-Java processes命令行的工具ExecHelper
- 用Jquery获取checkbox多个选项
- 数据库的运行监控
- Python入门级2
- hadoop在执行时出现 Caused by: java.lang.OutOfMemoryError: Java heap space
- 【华为练习题】十六进制字符串形式转为内存值形式
- 防止页面抖动
- 笔记--ThinkPHP的函数库
- python 在不同层级目录import 模块的方法
- [转] 接触C# 反射 2
- Oracle logmnr工具分析日志脚本
- RecyclerView的使用全解一
- Elasticsearch+Fluentd+Kibana的日志收集分析系统
- 一键GHOST光盘版官方版
- Java IO DataInputStream和DataOutputStream
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
- 保利威视Polyv点播集成
- DIV+CSS 命名规范
- eclipse安装git插件及使用