拯救公主
来源:互联网 发布:9.1越狱后无4g网络 编辑:程序博客网 时间:2024/06/11 11:13
多灾多难的公主又被大魔王抓走啦!国王派遣了第一勇士阿福去拯救她。
身为超级厉害的术士,同时也是阿福的好伙伴,你决定祝他一臂之力。你为阿福提供了一张大魔王根据地的地图,上面标记了阿福和公主所在的位置,以及一些不能够踏入的禁区。你还贴心地为阿福制造了一些传送门,通过一个传送门可以瞬间转移到任意一个传送门,当然阿福也可以选择不通过传送门瞬移。传送门的位置也被标记在了地图上。此外,你还查探到公主所在的地方被设下了结界,需要集齐K种宝石才能打开。当然,你在地图上也标记出了不同宝石所在的位置。
你希望阿福能够带着公主早日凯旋。于是在阿福出发之前,你还需要为阿福计算出他最快救出公主的时间。
地图用一个R×C的字符矩阵来表示。字符S表示阿福所在的位置,字符E表示公主所在的位置,字符#表示不能踏入的禁区,字符$表示传送门,字符.表示该位置安全,数字字符0至4表示了宝石的类型。阿福每次可以从当前的位置走到他上下左右四个方向上的任意一个位置,但不能走出地图边界。阿福每走一步需要花费1个单位时间,从一个传送门到达另一个传送门不需要花费时间。当阿福走到宝石所在的位置时,就视为得到了该宝石,不需要花费额外时间。
每一组数据的第一行包含了三个用空格分开的正整数R、C(2 <= R, C <= 200)和K,表示地图是一个R×C的矩阵,而阿福需要集齐K种宝石才能够打开拘禁公主的结界。
接下来的R行描述了地图的具体内容,每一行包含了C个字符。字符含义如题目描述中所述。保证有且仅有一个S和E。$的数量不超过10个。宝石的类型在数字0至4范围内,即不会超过5种宝石。
17 8 2..........S..#0..##..1...0#........1#......##E.....1....
11
#include <iostream>#include <algorithm>#include <cstring>#include <vector>#include <queue>using namespace std;/*感谢周洋师弟的帮助;简单的广搜;*/struct point{ int x, y, s, time; point (int xx, int yy, int ss, int tt):x(xx), y(yy), s(ss), time(tt){};};struct door{ int x, y;}door[15];int r,c,k;int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int min_time = 0;char mp[210][210];bool visited[210][210][1 << 5];//记录特定的发现宝石状态下,特定位置的被访问情况;bool check(int s, int k){//s为宝石发现情况; int cnt = 0;//记录已发现宝石的个数; for (int i = 0; i <= 4; i++) { if ((s >> i) & 1 == 1) cnt++; } return (cnt >= k);//集齐全部宝石;}bool bfs(int x, int y, int ex, int ey, int num_door, int k){ queue<point> qu; qu.push(point(x, y, 0, 0)); while (!qu.empty()) { point temp = qu.front(); qu.pop(); if (temp.x == ex && temp.y == ey && check(temp.s, k)) { min_time = temp.time; return true; } if (mp[temp.x][temp.y] == '.') { for (int i = 0; i < 4; i++) { int sx = temp.x + dx[i]; int sy = temp.y + dy[i]; if (sx >= 0 && sx < r && sy >= 0 && sy < c && mp[sx][sy] != '#' && visited[sx][sy][temp.s] == false) { visited[sx][sy][temp.s] = true; qu.push(point(sx, sy, temp.s, temp.time + 1)); } } } if (mp[temp.x][temp.y] >= '0' && mp[temp.x][temp.y] <= '4') { int s = temp.s | (1 << (mp[temp.x][temp.y] - '0')); for (int i = 0; i < 4; i++) { int sx = temp.x + dx[i]; int sy = temp.y + dy[i]; if (sx >= 0 && sx < r && sy >= 0 && sy < c && mp[sx][sy] != '#' && visited[sx][sy][s] == false) { visited[sx][sy][s] = true; qu.push(point(sx, sy, s, temp.time + 1)); } } } if (mp[temp.x][temp.y] == '$') { for (int i = 0; i < num_door; i++) { for (int j = 0; j < 4; j++) { int sx = door[i].x + dx[j]; int sy = door[i].y + dy[j]; if (sx >= 0 && sx < r && sy >= 0 && sy < c && mp[sx][sy] != '#' && visited[sx][sy][temp.s] == false) { visited[sx][sy][temp.s] = true; qu.push(point(sx, sy, temp.s, temp.time + 1)); } } } } } return false;}int main(){ int t; cin >> t; while (t--) { memset(visited,0,sizeof(visited)); int x, y, ex, ey; int cnt = 0;//记录传送门的数量; cin >> r >> c >> k; for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { cin >> mp[i][j]; if (mp[i][j] == '$') { door[cnt].x = i; door[cnt].y = j; cnt++; } if (mp[i][j] == 'S') { x = i; y = j; mp[i][j] = '.'; } if (mp[i][j] == 'E') { ex = i; ey = j; mp[i][j] = '.'; } } } if (bfs(x, y, ex, ey, cnt, k)) cout << min_time << endl; else cout << "oop!" << endl; } return 0;}
1 0
- 拯救公主
- 拯救公主
- 动作冒险游戏《拯救公主》
- OpenJudge-7221:拯救公主
- openjudge 拯救公主
- opj 7221 拯救公主
- bzoj3007 拯救小云公主
- 数据结构实训----拯救公主
- 百炼4105:拯救公主
- openjudge-4105-拯救公主-(bfs+)
- 【NOI OJ】 2.5 搜索 7221 拯救公主
- OJ 4105 拯救公主__广搜
- BZOJ 3007: 拯救小云公主
- BZOJ 3007 拯救小云公主 二分答案+对偶图
- 双向广度搜索 —— 拯救公主(一)
- 双向搜索+DP——拯救公主(二)
- poj 4105 拯救公主(bfs+二进制状态压缩)
- 期末考试-拯救公主(算法基础 第10周)
- MongoDB学习笔记(五) MongoDB文件存取操作
- 玩转Andorid---UI篇---两种进度条(ProgressBar)
- MongoDB学习笔记(六) MongoDB索引用法和效率分析
- JAVA基础针对自己薄弱环节总结01(循环之前的知识)
- 存储过程的优缺点个人总结
- 拯救公主
- 设置软件只能运行一个
- Android完全退出应用程序的方法
- 欢迎使用CSDN-markdown编辑器
- java多线程-专题-聊聊并发(四)深入分析ConcurrentHashMap
- uboot移植时自己修改也正确,但是却make不成功的问题
- Eclipse导入Hadoop源码项目
- Android休眠唤醒实例(自用)
- js加载函数addLoadEvent()