ABC071-C Together を解いてみた
今回のC問題はデータ構造を作ることができれば一瞬で解ける問題でした。
以下問題
問題
Together
実行時間制限: 2 sec / メモリ制限: 256 MB
問題文
長さ N の整数列 a1,a2,...,aN が与えられます。
各 1≤i≤Nに対し、ai に 1 足すか、1引くか、なにもしないかの三つの操作からどれか一つを選んで行います。
この操作の後、ある整数 Xを選んで、ai=X となる i の個数を数えます。
うまく操作を行い、Xを選ぶことで、この個数を最大化してください。
考えたこと
一つ一つ足して引いてのシミュレーションを行っていると O(N3) になってくるのでTLEになってしまいます。
視点を変えるとO(N)で問題が解けるようになります。
該当要素の+1 - 1を + 1 して配列としてデータをもって置けばO(N)で計算が終了します。
この時配列に作るデータの注意点は +1 -1 が配列の要素外にならないようにする点です。
フロー
- 入力の受け取り
- 数列を受け取りながら以下の処理を行う
- 数列の要素の値を受け取る
- 要素 - 1 と 要素 + 1の変数を作る
- -1 要素が0以上 かつ +1 要素が 109 以内ならば以下の処理
- 3つの要素の該当部分を+1
- -1要素が範囲外の場合
- 該当要素と+1要素を+1
- +1要素が範囲外の場合
- 該当要素と-1要素を+1
- 作った配列を線形的に探索
- そのなかでの最大値をとる
- 最大値を出力
プログラム
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main(void){ long long N; long long MAX = 100000; vector<long long> a(MAX); for(long long i = 0; i < MAX; i++){ a[i] = 0; } cin >> N; for(long long i = 0;i < N; i++){ long long tmp,dec,inc; cin >> tmp; dec = tmp - 1; inc = tmp + 1; if(dec >= 0 && inc < MAX){ a[dec]++; a[tmp]++; a[inc]++; }else if(dec < 0){ a[tmp]++; a[inc]++; }else if(inc >= MAX){ a[tmp]++; a[dec]++; } } long long mx = 0; for(long long i = 0; i < MAX; i++){ mx = max(mx,a[i]); } cout << mx << endl; return 0; }
こんな感じでACをとれることができました。