题目链接:https://ac.nowcoder.com/acm/contest/6607/D
Description
万物皆虚,万事皆允,玩过刺客信条的人对这句话应该都不会感到陌生
小A也是非常痴迷于这款游戏,正巧最近《刺客信条·奥德赛》发布了,然而其高昂的价格让小A苦恼不已
于是,小A只好重玩一次最经典的刺客信条2,来抚慰自己受伤的心灵
按照刺客信条2的剧情,艾吉奥需要前往威尼斯,从圣殿骑士手里夺取金苹果,然后前往罗马梵蒂冈刺杀教皇,拿取伊甸园神器“教皇权杖”
但是由于小A已经玩过很多次这个游戏了,他对剧情和地图了如指掌,现在已经轻而易举地拿到了金苹果,返回到了佛罗伦萨的庄园
接下来,小A就将操控艾吉奥从佛罗伦萨庄园出发,前往梵蒂冈,夺取教皇权杖。
在整个过程中,每经过一个建筑,都需要花费一定的时间,需要特别注意的是,由于圣母百花大教堂、圣马可大教堂、乔托钟楼都有众多圣殿骑士守护,经过这三个地方时,你需要花费100的时间
小A已经急不可耐地想要通关了,所以希望花费最少的时间到达梵蒂冈,请你帮他计算一下,从佛罗伦萨庄园到梵蒂冈,最快需要多少时间?
Input
第一行有两个整数,表示地图的行数n和列数m,地图为一个n×m的矩阵
接下来有n行,每行m个字符,每个字符是一个数字或大写字母,数字表示经过该建筑需要的时间,字母表示特定建筑(S表示佛罗伦萨的庄园,即起点;E表示梵蒂冈,即终点;A表示圣母百花大教堂;B表示圣马可大教堂;C表示乔托钟楼;A、B、C在每组数据中至多出现一次),每个字符或数字之间用空格分隔
为了降低游戏难度,小A特意调小了地图
0≤n,m≤30
Output
输出一个整数,从佛罗伦萨庄园到梵蒂冈的最小用时T
Sample Input
3 3
S A E
1 2 3
1 B 3
Sample Output
6
Solution
显然这是个BFS的题,不过如果只用普通队列是不行的,因为有特定建筑的存在,导致最短距离不一定用时最短。这里我们可以使用一下优先队列,每次拿出用时最短的那个点去更新,直到到达终点即可。
Code
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<set>
#include<queue>
#include<map>
using namespace std;
#define ll long long
char f[31][31];
bool vis[31][31];
int dx[4] = { 0,1,0,-1 };
int dy[4] = { 1,0,-1,0 };
int n, m, q, sx, sy, ex, ey;
struct node
{
int x, y, t;//t表示起点到达点(x,y)所花的时间
node(int m_x = 0, int m_y = 0, int m_time = 0) :x(m_x), y(m_y), t(m_time) {}
bool operator<(const node& a) const {
return t > a.t;
}
};
int bfs() {
priority_queue<node> p;
p.push(node(sx, sy, 0));
while (!p.empty())
{
node temp = p.top();
p.pop();
if (vis[temp.x][temp.y]) continue;
vis[temp.x][temp.y] = 1;
int xx, yy;
for (int i = 0; i < 4; i++) {
xx = temp.x + dx[i];
yy = temp.y + dy[i];
if (xx == ex && yy == ey) return temp.t;
if (xx >= 0 && yy >= 0 && xx < n && yy < m && vis[xx][yy] == 0) {
if(f[xx][yy]=='A'||f[xx][yy]=='B'||f[xx][yy]=='C') p.push(node(xx, yy, temp.t + 100));
else p.push(node(xx, yy, temp.t + int(f[xx][yy]-48)));
}
}
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
vis[i][j] = 0;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> f[i][j];
if (f[i][j] == 'S') {
sx = i; sy = j;
}
else if (f[i][j] == 'E') {
ex = i; ey = j;
}
}
}
cout << bfs() << endl;
return 0;
}
感觉有帮助的话,点个赞再走吧!