CF1923B

题解 · 2024-02-26

https://codeforces.com/contest/1923/problem/B

题意

您正在玩一款电脑游戏。游戏的当前关卡可以用一条直线来模拟。你的角色位于这条直线的 $0$ 点。有 $n$ 个怪物试图杀死你的角色;其中 $i$ 个怪物的健康值等于 $a_i$ ,并且最初位于 $x_i$ 点。

每秒钟都会发生以下情况:

  • 首先,你最多向怪物发射 $k$ 颗子弹。每颗子弹的目标正好是一个怪物,并使其生命值减少 $1$ 。对于每颗子弹,你可以任意选择目标(例如,你可以将所有子弹都射向一个怪物,也可以将所有子弹都射向不同的怪物,或者选择任何其他组合)。任何怪物都可以成为子弹的目标,不受其位置和其他因素的影响;
  • 然后,所有健康值为 $0$ 或更低的活着的怪物死亡;
  • 然后,所有活着的怪物向您移动 $1$ 点(在您左边的怪物坐标增加 $1$ ,在您右边的怪物坐标减少 $1$ )。如果有怪物接近你的角色(移动到 $0$ 点),你就输了。

你能在杀死所有 $n$ 只怪物的同时,不让任何一只怪物靠近你的角色吗?

题解

我们每秒钟都将 $k$ 发子弹射击最近的若干怪物,模拟过程即可。

#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 300010;
int t, n, k;
struct E {
  int v, p;
} a[maxn];
bool cmp (E x, E y) {
  return x.p < y.p;
}
int main () {
  ios::sync_with_stdio (false);
  cin.tie (0);
  cin >> t;
  while (t--) {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) cin >> a[i].v;
    for (int i = 1; i <= n; i++) cin >> a[i].p, a[i].p = abs (a[i].p);
    sort (a + 1, a + n + 1, cmp);
    bool flag = true;
    for (int ti = 1, tot = 1; flag && tot <= n && ti <= n; ti++) {
      int x = k;
      while (x > 0 && tot <= n) {
        int tmp = min (a[tot].v, x);
        a[tot].v -= tmp; x-= tmp;
        if (a[tot].v <= 0) tot++;
      }
      if (tot <= n && a[tot].p - ti <= 0) flag = false; 
    }
    cout << (flag ? "YES" : "NO") << '\n';
  }
  return 0;
}
Theme Jasmine by Kent Liao