奇数数组
输入正整数n和长度为n(n ≤ 105)的数列an(1 ≤ ai ≤ 109)。在一次操作中你可以选择一个偶数c,并且把所有等于c的数除以2。例如a = [6,8,12,6,3,12],选择c = 6进行一次操作后a = [3,8,12,3,3,12]。请问最少进行多少次操作后, 𝑎𝑛 的所有数都变成奇数。请尝试设计算法进行计算。
样例输入
6
40 6 40 3 20 1
样例输出
4
个人思路
思路
本题应该采用贪心策略,每次选择数组中最大的偶数作为操作数,然后遍历整个数组并对与操作数相等的数进行除2操作,直到数组中全部为奇数为止
贪心策略证明:设当前有四个偶数并满足a > b > c > d。根据贪心策略,第一次取操作数为a,得到数组[a/2,b,c,d]:
- if(a/2 > b),第二次操作数为a/2,得到的数组为[a/4,b,c,d]
- else if(a/2 == b),第二次操作数为a/2,得到的数组为[a/4,b/2,c,d]
- else(即a/2 < b),第二次操作数为b,得到的数组为[a/2,b/2,c,d]
显然取最大的数字作为操作数时,有可能同时对两个及以上个数的元素进行除2操作,因此是最优选择
注意
- 使用双端队列deque,便于在初始化时对数组进行排序操作
- deque中只保存偶数元素
- 操作过程中,如果出现偶数直接删去
- 每次对deque遍历后,要对序列进行排序,由于此时序列基本有序,因此采用插排更有效率
个人思路代码
/*
* @Author: LLX
* @Date: 2020-10-31 19:19:03
* @Last Modified by: SEUer
* @Last Modified time: 2020-10-31 21:03:58
*/
//记录偶数,记录最大的数字
#include<bits/stdc++.h>
using namespace std;
deque<int> arr;
int n, ans;
void insertSort(){
//对于基本有序的数组,插排效率更高
int index = 0;
for(int i =