公式
H - 3 枚階段 / Discarding Triplets 解説
by
H - 3 枚階段 / Discarding Triplets 解説
by
KoD
\(x, x+1, x+2\) が書かれたカードが存在するような整数 \(x\) であって、最小のものをとります。最終的に \(x\) が捨てられないならば、\(x+1, x+2\) のいずれか片方は必ず捨てられているとしてよいです。\(x+1\) が捨てられているならば、\(x+1, x+2, x+3\) が書かれたカードが一回の操作で捨てられたことになるので、この操作を取りやめ、\(x, x+1, x+2\) を代わりに捨てても最後に残るカードの数は変わりません。\(x+1\) が捨てられず、\(x+2\) が捨てられた場合は、\(x+2,x+3,x+4\) を捨てる操作を取りやめて \(x, x+1, x+2\) を代わりに捨ててもよいです。
よって、このような \(x\) に対し、\(x, x+1, x+2\) が書かれたカードを捨てる操作を必ず行うとしてよいです。以上から、
- 残っているカードに書かれた数の最小値を \(x\) とする
- \(x, x+1, x+2\) が書かれたカードが存在するか調べる。存在するならそれらをまとめて捨て、存在しないなら \(x\) は操作後に残るカードとして数える
という操作を繰り返し行うことでこの問題を解くことができます。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
multiset<long long> a;
while (n--) {
long long x;
cin >> x;
a.insert(x);
}
int ans = 0;
while (!a.empty()) {
const long long x = *a.begin();
a.erase(a.begin());
if (a.find(x + 1) != a.end() and a.find(x + 2) != a.end()) {
a.erase(a.find(x + 1));
a.erase(a.find(x + 2));
} else {
ans += 1;
}
}
cout << ans << '\n';
return 0;
}
投稿日時:
最終更新:
