NC207569 牛牛爱奇数

题目链接

题目

题目描述

在牛牛面前放着 \(n\) 个数,这些数字既有奇数也有偶数,只不过牛牛对奇数情有独钟,他特别想让这些数都变成奇数。

现在牛牛获得了一种能力,他可以执行一种操作:每次选中一个偶数,然后把这些数中与该数相等的数都除以 \(2\) ,例如现在有一个数组为\([2,2,3]\) ,那么牛牛可以执行一次操作,使得这个数组变为 \([1,1,3]\)

牛牛现在想知道,对于任意的 \(n\) 个数,他最少需要操作多少次,使得这些数都变成奇数?

示例1

输入

3,[2,2,3]

返回值

1

说明

只需做一次操作,会将其中的偶数 \(2\) 都变成 \(1\) ,满足了所有的数都是奇数的要求。

示例2

输入

3,[1,3,7]

返回值

0

说明

不需要做任何操作,因为所有的数原本就是奇数。

备注

\(1 \leq n \leq 10^{6}\) ,代表一个有多少数字

\(a_{1},a_{2},a_{3}...a_{n}(1 \leq a_{i} \leq 10^{9})\) 代表数字的大小

对于 \(25\%\) 的数据, \(1 \leq n \leq 10^{2},1 \leq a_{i} \leq 10^{3}\)

对于 \(75\%\) 的数据, \(1 \leq n \leq 10^{4},1 \leq a_{i} \leq 10^{6}\)

对于 \(100\%\) 的数据, \(1 \leq n \leq 10^{6},1 \leq a_{i} \leq 10^{9}\)

题解

知识点:贪心,STL,优先队列。

先把偶数放进优先队列从大到小排,因为大的偶数可能变成已有的小偶数,用小偶数除一次即可,因此从大的偶数开始除。并且因为同一个数字只要除一次,所以把一个除完的数字放回队列即可,剩下的同种数字全部弹出。

时间复杂度 \(O(n \log n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>

using namespace std;

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    priority_queue<int> pq;
    for (int i = 0, tmp;i < n;i++) {
        cin >> tmp;
        if (!(tmp & 1)) pq.push(tmp);
    }
    int ans = 0;
    while (!pq.empty()) {
        ans++;
        int x = pq.top();
        while (!pq.empty() && pq.top() == x) pq.pop();
        x >>= 1;
        if (!(x & 1)) pq.push(x);
    }
    cout << ans << '\n';
    return 0;
}
posted @ 2022-07-09 16:54  空白菌  阅读(18)  评论(0编辑  收藏  举报