Official
C - Participants 3 Editorial
by
C - Participants 3 Editorial
by
Forested
さまざまな解法が考えられます。
\(\Theta(NM)\) 時間の解法
列挙する数は必ず \(B\) に現れます。よって、 \(B\) の数全てについて \(A\) に現れるかどうかを判定することで列挙ができます。一回の判定に \(\Theta(N)\) 時間かけると、全体の計算量は \(\Theta(NM)\) 時間になります。
n, m = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
ans = [x for x in b if a.count(x) == 0]
print(len(ans))
for num in ans:
print(num)
\(\Theta((N + M) \log N)\) 時間の解法
上の解法ではある数が \(A\) に含まれるかどうかの判定に一回あたり \(\Theta(N)\) 時間かけていました。 \(A\) をあらかじめソートしておくと二分探索が適用でき、一回の判定が \(\Theta(\log N)\) 時間になります。ソートに \(\Theta(N \log N)\) 時間かけると、全体の計算量は \(\Theta((N + M) \log N)\) になります。
# a に x が含まれるかを二分探索で判定
def binary_search(a, x):
low, high = -1, len(a)
while high - low > 1:
mid = (high + low) // 2
if a[mid] >= x:
high = mid
else:
low = mid
return high != len(a) and a[high] == x
n, m = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
a.sort()
ans = [x for x in b if not binary_search(a, x)]
print(len(ans))
for num in ans:
print(num)
\(\Theta(\mathrm{MAX})\) 時間の解法
\(\mathrm{MAX}\) を \(A\) と \(B\) に含まれる数の最大値とします。ある数 \(x\) が \(A\) の中に現れるかと \(B\) の中に現れるかはそれぞれ長さ \(\mathrm{MAX} + 1\) の配列で管理できます。時間計算量は \(\Theta(\mathrm{MAX})\) です。
n, m = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
MAX = 3000
a_count = [False] * (MAX + 1)
for x in a:
a_count[x] = True
b_count = [False] * (MAX + 1)
for x in b:
b_count[x] = True
ans = [x for x in range(MAX + 1) if not a_count[x] and b_count[x]]
print(len(ans))
for num in ans:
print(num)
補足
\(A\) と \(B\) を集合とみなすと、この問題で計算したいものは差集合 \(B \setminus A\) です。差集合を求める関数や演算子が用意されている言語では、それを使うと自分で実装する必要がなく、簡単にこの問題を解くことができます。
n, m = map(int, input().split())
a = set(map(int, input().split()))
b = set(map(int, input().split()))
ans = b - a
print(len(ans))
for num in ans:
print(num)
posted:
last update:
