传送门:洛谷 Vlad and Division | Codeforces D. Vlad and Divison

更佳的阅读体验:CF1926D 题解


简要题意:两个二进制下第 $1$ 到 $31$ 位都不同的数可以组合成一组,一个单独的数也可以成为一组。有 $n$ 个数,求最少可以构成多少组。

二进制下,每一位只可能是 $0$ 或 $1$,所以对于一个数,在二进制下 $1$ 到 $31$ 位都不同的数是唯一的,并且这两个数的和是一定的,即 $2147483647$($2^{31} - 1$)。

考虑使用 map 维护每个数出现的数量。读入时存下每个数的数量,然后遍历整个序列,如果发现当前数 $a_i$ 和 $2147483647 - a_i$ 都有出现,那么即可贪心地凑成一对。

#include <iostream>
#include <map>
using namespace std;
using ll = long long;

const int N = 2e5 + 10, LIM = 2147483647;
int t, n, a[N], ans;
map<int, int> mp;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    for (cin >> t; t; --t) {
        ans = 0, mp.clear();
        cin >> n;
        for (int i = 1; i <= n; ++i) cin >> a[i], ++mp[a[i]];
        for (int i = 1; i <= n; ++i) if (mp[a[i]]) {
            --mp[a[i]];
            if (mp[LIM - a[i]]) --mp[LIM - a[i]];
            ++ans;
        } cout << ans << '\n';
    } return 0;
}

后记

Verdict: Hacked

没事别用 unordered_map,血的教训。

最后修改:2024 年 02 月 23 日
如果觉得我的文章对你有用,请随意赞赏