AtCoder[ABC271C] Manga
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 1;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n;
cin >> n;
vector<int>A(N);
for (int i = 0; i < n; i++) {
cin >> A[i];
--A[i]; //书籍是从1开始的,而数组下标从0开始,统一下标索引。
}
int l = 0, r = N;
while (l < r - 1) {
int cnt=0, cnt2 = 0;
int mid = l + r >> 1;
vector<int>h(mid, 0);//每轮循环都要初始化为0,重新统计
for (int i = 0; i < n; i++) {
if (A[i] < mid) {
h[A[i]]++;//统计连续书籍
}
else {
++cnt;//统计不连续书籍
}
}
for (int i = 0; i < mid; i++) {
if (h[i] == 0) {
++cnt2;//统计未出现的书籍
}
if (h[i] >= 2) {
cnt += h[i] - 1;//重复书籍也算不连续书籍,更正不连续书籍
}
}
if ((cnt2 << 1) <= cnt)l = mid;
else r = mid;
}
cout << l;
}
总结:运用二分,将满足连续数字的放一边,不连续的放另外一边,不断调整更新边界l,r与mid,直到满足题意为止。