【补题】牛客周赛 Round 33

本文介绍了如何将地下城中击杀怪物的血量作为边权,运用Dijkstra算法计算从起点到终点的最短路径,确保主角的生命值足以安全到达终点。作者在比赛中反思了图论知识的不足。
摘要由CSDN通过智能技术生成

链接:https://ac.nowcoder.com/acm/contest/75630

E-小红勇闯地下城

思路

dijkstra模版题,把击杀怪物的血量看作边权,计算起点到终点的最短路,如果路径长度大于等于生命值,则能够安全到达终点。(比赛时居然没想到,一直在BFS,图论太差了T_T)

代码

#include <bits/stdc++.h>

using namespace std;

int q, n, m, h, dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};

struct Comparator {
  bool operator()(const array<int, 3>& a, const array<int, 3>& b) {
    return a[2] > b[2];
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> q;
  while (q--) {
    cin >> n >> m >> h;
    int tx, ty;
    vector<string> v(n);
    vector<vector<int>> dis(n, vector<int>(m, INT_MAX));
    vector<vector<bool>> vis(n, vector<bool>(m, false));
    priority_queue<array<int, 3>, vector<array<int, 3>>, Comparator> pq;
    for (int i = 0; i < n; i++) {
      cin >> v[i];
      for (int j = 0; j < m; j++) {
        if (v[i][j] == 'S') {
          v[i][j] = '0';
          dis[i][j] = 0;
          pq.push({i, j, 0});
        } else if (v[i][j] == 'T') {
          tx = i;
          ty = j;
          v[i][j] = '0';
        }
      }
    }
    while (!pq.empty()) {
      auto a = pq.top();
      pq.pop();
      if (vis[a[0]][a[1]]) {
        continue;
      }
      vis[a[0]][a[1]] = true;
      for (auto& d : dir) {
        int x = a[0] + d[0], y = a[1] + d[1];
        if (0 <= x && x < n && 0 <= y && y < m &&
            dis[x][y] > dis[a[0]][a[1]] + v[x][y] - '0') {
          dis[x][y] = dis[a[0]][a[1]] + v[x][y] - '0';
          if (!vis[x][y]) {
            pq.push({x, y, dis[x][y]});
          }
        }
      }
    }
    if (dis[tx][ty] >= h) {
      cout << "No\n";
    } else {
      cout << "Yes\n";
    }
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值