ちょっとした考察が必要になる問題。
問題概要
整数からなる数列 が与えられる。数列の各要素に対して「何もしない」「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; }