読者です 読者をやめる 読者になる 読者になる

AOJ 0517 Longest Steps

解法

しゃくとり法でやった.
与えられた k 枚のカードをソートしておく.
0が含まれていれば1つだけ飛ばせるので,それは場合分けで処理.
行けるところまでいったら,左端をカードの数字が1以上飛んでいるところに更新する.

オーダーはソートがネックなので O(klogk + k).

しかし,連続部分を pair でもっておいて,0 が含まれていれば隣り合う連続区間をつなげる,みたいな実装の方が自然かもしれない.

ソースコード

#include <bits/stdc++.h>
using namespace std;
 
int main() {
    int n, k;
    while(cin >> n >> k, n) {
        vector<int> v(k);
        for(int i=0; i<k; ++i) {
            cin >> v[i];
        }
        sort(v.begin(), v.end());
        int f = v[0] == 0;
        int l = 0+f, r = 1+f, cnt = 0, next_l = -1;
        int res = 0;
        while(true) {
            next_l = -1;
            while(r < k && (v[r] - v[r-1] == 1 || v[r] - v[r-1] == 2)) {
                if(v[r] - v[r-1] == 1) {
                    r++;
                } else if(cnt < f) {
                    cnt++;
                    next_l = r;
                    r++;
                } else {
                    break;
                }
            }
            res = max(res, r - l + ((r == k && cnt < f) || cnt));
            if(r == k) {
                break;
            }
            if(next_l == -1) {
                l = r;
                r++;
            } else {
                l = next_l;
            }
            cnt = 0;
        }
        cout << res << endl;
    }
}