ちょっとした考察が必要になる問題。
問題概要
整数からなる数列 が与えられる。数列の各要素に対して「何もしない」「1 を足す」「1 を引く」をしていく。
操作後に、整数値 を選ぶ。 となる の個数の最大値を求めよ。
制約
考えたこと
問題文では操作後に整数値 を選んでいるが、整数値 を先に選んでから操作しても、一向に構わない。
そこで、整数値 を仮決めしたときに、数列をどのように操作すれば良いかを考えてみよう。少し考えると、次のように結論付けられる。
- のとき:何もしない
- のとき:1 を足す
- のとき:1 を引く
- の値がそれ以外のとき:どうしようもない( には一致させられない)
このことから、 を決めたときのスコアは次のようになる。
となるような の個数
これを効率よく求めるために、次のバケットを用意しよう( なので、サイズは 程度で十分)。
nums[x]
:数列 の中の、 の個数
これを求めておけば、上記のスコアは効率よく求められる。あとは、 の値として、 から 程度まで試していけば良い。
計算量は、 として、 と評価できる。
コード
#include <bits/stdc++.h> using namespace std; int main() { const int MAX = 110000; int N, a; cin >> N; vector<int> nums(MAX, 0); for (int i = 0; i < N; i++) { cin >> a; nums[a]++; } int res = 0; for (int x = 1; x+1 < MAX; x++) { int num = nums[x-1] + nums[x] + nums[x+1]; res = max(res, num); } cout << res << endl; }