Official

C - Not All Editorial by yuto1115

解説

\(1\) 以上 \(M\) 以下の整数であって \(A\) の中に含まれないようなものが存在するようになるまで、\(A\) の末尾の要素を削除し続ければよいです。これをより具体的なアルゴリズムとして記述すると以下のようになります。

  1. 整数 \(N,M\)、配列 \(A\) を入力として受け取る。
  2. 変数 \(\texttt{ans}\) を用意し、\(0\) で初期化する。
  3. 長さ \(M\) の真偽値型の配列 \(\texttt{exist}\) を用意し、すべての要素を \(\texttt{false}\) で初期化する。
  4. \(i=1,2,\dots,|A|\) それぞれについて(\(|A|\) は現時点での \(A\) の長さ)、\(\texttt{exist}[A[i]]\)\(\texttt{true}\) を代入する。
  5. 配列 \(\texttt{exist}\) の要素の中に \(\texttt{false}\)\(1\) つでも存在するならば、\(\texttt{ans}\) の値を出力してプログラムを終了する。そうでないならば、\(A\) の末尾の要素を削除し、\(\texttt{ans}\)\(1\) を加算して、3. に戻る。

具体的な実装方法については下記の実装例 (C++, Python) を参考にしてください。配列の添字が \(0\) から始まる言語 (C++, Python を含む主要な言語はほぼ全てが該当) においては、\(A\) を入力として受け取った段階ですべての要素から \(1\) を引いておくと、添字に関係する実装ミスを回避しやすくなります。

実装例 (C++) :

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        --a[i];
    }

    int ans = 0;
    while (true) {
        vector<bool> exist(m);
        for (int i: a) exist[i] = true;
        bool ok = false;
        for (bool b: exist) {
            if (!b) ok = true;
        }
        if (ok) break;
        ++ans;
        a.pop_back();
    }

    cout << ans << endl;
}

実装例 (Python) :

n, m = map(int, input().split())
a = list(map(int, input().split()))
for i in range(n):
  a[i] -= 1

ans = 0
while True:
    exist = [False] * m
    for i in a:
        exist[i] = True
    ok = False
    for b in exist:
      if not b:
        ok = True
    if ok:
        break
    ans += 1
    a.pop()

print(ans)

posted:
last update: