Official
D - Wi-Fiスポットの接続 / Wi-Fi Spot Connection Editorial
by
D - Wi-Fiスポットの接続 / Wi-Fi Spot Connection Editorial
by
kyopro_friends
区間 \([0,L]\) を時刻だと思うことで、問題は次のように読み替えることができます:
「\(N\) 個の Wi-Fi ルーターがあります。\(i\) 個目のルータは時刻 \(X_i-R_i\) に ON になり、時刻 \(X_i+R_i\) に OFF になります。時刻 \(0\) から \(L\) まで常に少なくとも1つのルーターが ON ですか?」
番兵として、時刻 \(L\) に ON になるルーターを追加しておきます。このルーターは時刻 \([0,L]\) の範囲に影響を与えないため、答えに影響を与えません。
この問題は「次に全てのルーターが OFF になる時刻」を保持しながら、時刻順にルーターが ON になるイベントを確認し、保持した情報を次のように更新すればよいです。
- 「次に全てのルーターが OFF になる時刻」を 0 で初期化する
- ON になる時刻が早いルーターから順に以下を行う
- ON になる時刻が「次に全てのルーターが OFF になる時刻」より後である場合、その間で全てのルーターが OFF になっているため答えは
No - そうでない場合、そのルーターがOFFになる時刻を確かめ、「次に全てのルーターが OFF になる時刻」を更新する
- ON になる時刻が「次に全てのルーターが OFF になる時刻」より後である場合、その間で全てのルーターが OFF になっているため答えは
- 全てのルーターを処理できたら答えは
Yes(制約より最後に処理されるのは番兵であり、番兵の存在により「次に全てのルーターが OFF になる時刻」が \(L\) 以降であることがわかるため)
実装例 (C++)
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, l;
cin >> n >> l;
vector<pair<int, int>> rooter;
rooter.push_back({l, l}); // 番兵
for(int i=0; i<n; i++){
int x, r;
cin >> x >> r;
rooter.push_back({x-r, x+r});
}
sort(rooter.begin(), rooter.end());
int end = 0;
for (auto [on, off]: rooter) {
if(on > end){
cout << "No" << endl;
return 0;
}
end = max(end, off);
}
cout << "Yes" << endl;
}
実装例 (Python)
N, L = map(int,input().split())
rooter = [(L, L)] # 番兵
for _ in range(N):
X, R = map(int,input().split())
rooter.append((X-R, X+R))
rooter.sort()
end = 0
for on, off in rooter:
if on > end:
print("No")
break
end = max(end, off)
else:
print("Yes")
posted:
last update:
