とても教育的な問題ですね。
問題概要
0 以上 9 以下の整数からなる、 個の整数 が与えられる。
数列 の中に一度以上登場する整数を小さい順に出力せよ。
解法 (1):値 0, 1, ..., 9 について個別に全探索
1 つめの解法は
- まず、値 0 が数列に含まれているかどうかを判定し、含まれていれば 0 を出力する
- 次に、値 1 が数列に含まれているかどうかを判定し、含まれていれば 1 を出力する
- 次に、値 2 が数列に含まれているかどうかを判定し、含まれていれば 2 を出力する
- ...
- 最後に、値 9 が数列に含まれているかどうかを判定し、含まれていれば 9 を出力する
という方法だ。
コード
#include <bits/stdc++.h>
using namespace std;
int main() {
int N;
cin >> N;
vector<int> A(N);
for (int i = 0; i < N; ++i) cin >> A[i];
for (int v = 0; v <= 9; ++v) {
bool exist = false;
for (int i = 0; i < N; ++i) {
if (A[i] == v) {
exist = true;
}
}
if (exist) {
cout << v << endl;
}
}
}
解法 (2):バケット
解法 1 よりも高速な解法がある。それは次の配列 (しばしばバケットと呼ばれる) を用意することだ。公式解説もこの方法を解説している。
exist[v]
← 数列の中に値 の要素が存在するかどうかを表すブール値 (True / False)
最初は配列 exist
全体を False で初期化しておき、for
文を 1 回回して、各 i
に対して
exist[A[i]] = true;
とすることで、配列 exist
が求められる。
配列 exist
が求められたら、あとは exist[0]
, exist[1]
, ..., exist[9]
を順に調べて True である場合には対応する値を出力すればよい。
余談
なお、解法 (1) よりも解法 (2) の方が、計算量の観点では優れている。計算量については次の記事などで解説している。
qiita.com
コード
#include <bits/stdc++.h>
using namespace std;
int main() {
int N;
cin >> N;
vector<int> A(N);
for (int i = 0; i < N; ++i) cin >> A[i];
vector<bool> exist(10, false);
for (int i = 0; i < N; ++i) exist[A[i]] = true;
for (int v = 0; v <= 9; ++v) {
if (exist[v]) {
cout << v << endl;
}
}
}