これかなりいい問題だと思う!!!
テスターをしていて、最初は 3 人じゃなくて 人だったけど、3 人にしたことでいい感じに 300 点問題になった!
問題概要
人がいて、それぞれレーティングは
となっている。
人の中から 3 人を選ぶ方法のうち、3 人のレーティングの最大値と最小値との差が
以下であるようなものが何通りあるか、求めよ。
制約
解法
この手の問題は最初に 人をレーティングの小さい順にソートしてしまうと考えやすくなる。
そして「3 人のうちレーティングが最小の人」を誰にするのかを固定して考えることにする。 人目をレーティング最小の人としたとき、
を満たす最大の
をとる
- このとき
の中からどのように 2 人選んでもよい
- その選び方は
通りある
という風になる。あとは各 に対して、
を満たす最大の
が求められれば OK。これはしゃくとり法 (か lower_bound) を使えば OK。
全体として の計算量で解ける。
#include <bits/stdc++.h> using namespace std; int main() { int N, D; cin >> N >> D; vector<int> a(N); for (int i = 0; i < N; ++i) cin >> a[i]; sort(a.begin(), a.end()); long long res = 0; int j = 0; for (int i = 0; i < N; ++i) { while (j < N && a[j] <= a[i] + D) ++j; --j; res += (long long)(j-i) * (j-i-1) / 2; } cout << res << endl; }