ACM-ICPC 2018青岛网络赛-A题 Saving Tang Monk II

做法:优先队列

题目1 : Saving Tang Monk II

时间限制:1000ms

单点时限:1000ms

内存限制:256MB

描述

《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, and he wanted to reach Tang Monk and rescue him.

The palace can be described as a matrix of characters. Different characters stand for different rooms as below:

‘S‘ : The original position of Sun Wukong

‘T‘ : The location of Tang Monk

‘.‘ : An empty room

‘#‘ : A deadly gas room.

‘B‘ : A room with unlimited number of oxygen bottles. Every time Sun Wukong entered a ‘B‘ room from other rooms, he would get an oxygen bottle. But staying there would not get Sun Wukong more oxygen bottles. Sun Wukong could carry at most 5 oxygen bottles at the same time.

‘P‘ : A room with unlimited number of speed-up pills. Every time Sun Wukong entered a ‘P‘ room from other rooms, he would get a speed-up pill. But staying there would not get Sun Wukong more speed-up pills. Sun Wukong could bring unlimited number of speed-up pills with him.

Sun Wukong could move in the palace. For each move, Sun Wukong might go to the adjacent rooms in 4 directions(north, west,south and east). But Sun Wukong couldn‘t get into a ‘#‘ room(deadly gas room) without an oxygen bottle. Entering a ‘#‘ room each time would cost Sun Wukong one oxygen bottle.

Each move took Sun Wukong one minute. But if Sun Wukong ate a speed-up pill, he could make next move without spending any time. In other words, each speed-up pill could save Sun Wukong one minute. And if Sun Wukong went into a ‘#‘ room, he had to stay there for one extra minute to recover his health.

Since Sun Wukong was an impatient monkey, he wanted to save Tang Monk as soon as possible. Please figure out the minimum time Sun Wukong needed to reach Tang Monk.

输入

There are no more than 25 test cases.

For each case, the first line includes two integers N and M(0 < N,M ≤ 100), meaning that the palace is a N × M matrix.

Then the N×M matrix follows.

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

输出

For each test case, print the minimum time (in minute) Sun Wukong needed to save Tang Monk. If it‘s impossible for Sun Wukong to complete the mission, print -1

样例输入
2 2
S#
#T
2 5
SB###
##P#T
4 7
SP.....
P#.....
......#
B...##T
0 0
样例输出
-1
8
11
  1 #include <iostream>
  2 #include <queue>
  3 #include <cstring>
  4 using namespace std;
  5
  6 char mp[110][110];
  7 bool vis[110][110][10000];
  8 int d[4][2] = { { 1,0 },{ -1,0 },{ 0,1 },{ 0,-1 } };
  9 int x, y;
 10
 11 struct node
 12 {
 13     int x, y;
 14     int step;
 15     int o;
 16     bool operator < (const node &a) const {
 17         return step > a.step;
 18     }
 19 };
 20
 21
 22 int bfs(node st)
 23 {
 24     priority_queue<node> q;
 25     st.step = 0;
 26     st.o = 0;
 27     q.push(st);
 28     node now, next;
 29
 30     while (!q.empty())
 31     {
 32         now = q.top();
 33         q.pop();
 34
 35         for (int i = 0; i < 4; i++)
 36         {
 37             next = now;
 38             next.step++;
 39             next.x += d[i][0];
 40             next.y += d[i][1];
 41             if (next.x < 0 || next.y < 0 || next.x >= x || next.y >= y)
 42                 continue;
 43             if (next.o == 0 && mp[next.x][next.y] == ‘#‘)
 44                 continue;
 45
 46             if (mp[next.x][next.y] == ‘T‘)
 47             {
 48                 return next.step;
 49
 50             }
 51
 52             if (mp[next.x][next.y] == ‘P‘)
 53                 next.step--;
 54             else if (mp[next.x][next.y] == ‘#‘)
 55             {
 56                 next.step++;
 57                 next.o--;
 58             }
 59             else if (mp[next.x][next.y] == ‘B‘)
 60             {
 61                 if(next.o < 5)
 62                     next.o++;
 63             }
 64
 65             if (vis[next.x][next.y][next.o])
 66                 continue;
 67
 68
 69             vis[next.x][next.y][next.o] = 1;
 70             q.push(next);
 71         }
 72     }
 73     return -1;
 74 }
 75
 76 int main()
 77 {
 78     ios::sync_with_stdio(false);
 79     cin.tie(0);
 80     cout.tie(0);
 81     while (cin >> x >> y && (x || y))
 82     {
 83         memset(vis, 0, sizeof(vis));
 84         memset(mp, ‘.‘, sizeof(mp));
 85         node st;
 86         for (int i = 0; i < x; i++)
 87             for (int j = 0; j < y; j++)
 88             {
 89                 cin >> mp[i][j];
 90                 if (mp[i][j] == ‘S‘)
 91                 {
 92                     st.x = i;
 93                     st.y = j;
 94                 }
 95             }
 96         cout << bfs(st) << endl;
 97     }
 98
 99     return 0;
100 }

原文地址:https://www.cnblogs.com/qq965921539/p/9690548.html

时间: 2024-07-31 11:51:47

ACM-ICPC 2018青岛网络赛-A题 Saving Tang Monk II的相关文章

ACM-ICPC 2018青岛网络赛-H题

把这题的每个点分成两种情况看,如果是从这个点开始,0算作2,1算作1,如果是中间点或者是结束点,如果和前面的相同看作2,不相同看作1 #include <iostream> #include <string> #include <string.h> using namespace std; int main() { ios::sync_with_stdio(false); int t; cin >> t; while (t--) { int a, b; st

ACM-ICPC 2018徐州网络赛-H题 Ryuji doesn&#39;t want to study

C*M....死于update的一个long long写成int了 心累 不想写过程了 ******** 树状数组,一个平的一个斜着的,怎么斜都行 题库链接:https://nanti.jisuanke.com/t/31460 #include <iostream> #include <cstring> #define ll long long #define lowbit(x) (x & -x) using namespace std; const int maxn =

HDU 5880 Family View (2016 青岛网络赛 C题,AC自动机)

题目链接  2016 青岛网络赛  Problem C 题意  给出一些敏感词,和一篇文章.现在要屏蔽这篇文章中所有出现过的敏感词,屏蔽掉的用$'*'$表示. 建立$AC$自动机,查询的时候沿着$fail$指针往下走,当匹配成功的时候更新$f[i]$ $f[i]$表示要屏蔽以第$i$个字母结尾的长度为$f[i]$的字符串. 原文地址:https://www.cnblogs.com/cxhscst2/p/8452147.html

ACM 2018 南京网络赛H题Set解题报告

题目描述 给定\(n\)个数$a_i$,起初第\(i\)个数在第\(i\)个集合.有三种操作(共\(m\)次): 1 $u$ $v$ 将第$u$个数和第$v$个数所在集合合并 2 $u$ 将第$u$个数所在集合所有数加1 3 $u$ $k$ $x$ 问$u$所在集合有多少个数模$2^k$余$x$. 数据范围:\(n,m \le 500000,a_i \le 10^9, 0 \le k \le 30\). 简要题解 显然此题可以用set加启发式合并在\(O(n \log ^2 n)\)时间复杂度解

ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 A.Saving Tang Monk II(优先队列广搜)

#include<bits/stdc++.h> using namespace std; const int maxN = 123; const int inf = 1e9 + 7; char G[maxN][maxN]; int times[maxN][maxN][6]; int n, m, sx, sy, ex, ey, ans; int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; struct node { int x, y, t, o; bool

hdu 4431 第37届ACM/ICPC 天津赛区现场赛A题 枚举

题意:就是给了13张牌.问增加哪些牌可以胡牌.m是数字,s是条,p是筒,c是数字 胡牌有以下几种情况: 1.一个对子 +  4组 3个相同的牌或者顺子.  只有m.s.p是可以构成顺子的.东西南北这样的牌没有顺子. 2.7个不同的对子. 3.1m,9m,1p,9p,1s,9s,1c,2c,3c,4c,5c,6c,7c.  这13种牌每种都有,而且仅有这13种牌.肯定是有一种2张.其他的1张. 模拟即可,第一个对子的情况需要枚举 很麻烦的模拟,但是貌似稳银的很需要这题,所以这种难度必须要弄懂,加油

2014 ACM/ICPC 鞍山赛区网络赛(清华命题)

为迎接10月17号清华命题的鞍山现场赛 杭电上的题目 Biconnected(hdu4997)      Rotate(hdu4998)     Overt(hdu4999)   Clone(hdu5000)   Walk(hdu5001)   LianLianKan   Rescue   Spy's Work   Color the Tree   The Ghost Blows Light   USACO ORZ   2013/8/27

2017 acm icpc 沈阳(网络赛)5/12 题解

比赛中较...能做的5道题 hdoj6195. cable cable cable 题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=6195 题目大意 : 略 规律 : 答案 = k+(m-k)*k hdoj6198. number number number 题目链接 : http://acm.hdu.edu.cn/showproblem.php?pid=6198 题目大意  : 给你一个整数n.问你n个斐波那契数(可重复)不能构成哪些数,输出

zoj 3659 第37届ACM/ICPC 长春赛区现场赛E题 (并查集)

题意:给出一棵树,找出一个点,求出所有点到这个点的权值和最大,权值为路径上所有边权的最小值. 用神奇的并查集,把路按照权值从大到小排序,然后用类似Kruskal的方法不断的加入边. 对于要加入的一条路,这条路连接这城市x和y,x所在的集合为A, y所在的集合为B, 可以确定A,B集合内的所有路都比当前这条路的权值大.如果让集合B加入集合A,就是让中心城市位于集合A,那么可以确定这两个集合合并之后的总权值为: A的权值总和+B的数量*当前这条路的权值.同样算出让集合B加入集合A的情况,取两者合并后