题解:P11231 [CSP-S 2024] 决斗(民间数据)
wangbinfeng · · 题解
考点:
- [ ]
【4】二分法; - [ ]
【5】快速排序或【3】算法模板库中的函数:min、max、swap、sort。
思路:
考虑到一个怪兽能打破一个
那么希望一个怪兽打破的怪兽是最近的小于它的怪兽(设这两个怪兽分别为
考虑逆向实现。具体地,先对输入的
本人使用了 lower_bound 代替手写二分,发现到寻找 lower_bound 寻找
时间复杂度
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 9;
int n, a[maxn], anss;
bitset<maxn> vis, ans;
signed main()
{
// freopen("dat.in", "r", stdin);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + n + 1);
for (int i = 1, k = 1; i <= n; i++)
{
k = lower_bound(a + k, a + n + 1, a[i] + 1 + vis[i]) - a; // 发现二分寻找的怪兽单调递增,那么二分的左端点可以直接赋值为上次的 k。
while (vis[k])
k++;
if (k > n)
continue;
vis[k] = true, a[k]--, ans[i] = true;
}
for (int i = 1; i <= n; i++)
anss += !ans[i];
cout << anss << endl;
// for (int i = 1; i <= n; i++)
// cerr << vis[i] << ' ';
// cerr << endl;
// for (int i = 1; i <= n; i++)
// cerr << ans[i] << ' ';
}