Official

C - 電波塔のカバー範囲 / Coverage Area of Radio Towers Editorial by kyopro_friends


この問題はイベントソートを用いることで解くことができます。

高橋君が数直線の左端から右端方向へ歩いていく過程をシミュレーションすることを考えます。

受信できる信号の強度は、電波塔の範囲に入るか、範囲の外に出るかしたときに変化します。よって、このような変化が起こる座標を昇順にソートすることでシミュレーションできます。

このような変化が起こる座標は高々 \(2N\) 個なので、 \(O(N\log N)\) で問題を解くことができます。

ある電波塔のカバー範囲の右端と左端がちょうど重なるケースに注意してください。
以下の実装例では、同じ座標に対する処理では新しく範囲に入る方を優先するため、座標と、電波の変化量の -1 倍の組を保持してソートしています。

実装例 (C++)

#include<bits/stdc++.h>
using namespace std;

int main(){
  int n;
  cin >> n;
  vector<pair<int,int>>data;
  for(int i=0; i<n; i++){
    int x, l, r, c;
    cin >> x >> l >> r >> c;
    data.push_back({x - l, -c});
    data.push_back({x + r, c});
  }
  sort(data.begin(), data.end());

  long long crr = 0, ans = 0;
  for(auto[_, c]: data){
    crr += -c;
    ans = max(ans, crr);
  }
  cout << ans << endl;
}

実装例 (Python)

N = int(input())
data = []
for _ in range(N):
  X, L, R, C = map(int, input().split())
  data.append((X - L, -C))
  data.append((X + R, C))

data.sort()
crr = 0
ans = 0
for _, c in data:
  crr += -c
  ans = max(ans, crr)

print(ans)

posted:
last update: