链接:https://ac.nowcoder.com/acm/contest/8563/A
来源:牛客网
题目描述
给一个数组,一共有n个数。
你能进行最多k次操作。每次操作可以进行以下步骤:
选择数组中的一个偶数ai,将其变成 ai/2 。
现在你进行不超过k次操作后,让数组中所有数之和尽可能小。请输出这个最小的和。
输入描述:
第一行输入两个正整数n和k,用空格隔开
第二行输入n个正整数ai
数据范围:
1≤n≤100000,1≤k≤109
1≤ai≤10^9
输出描述:
一个正整数,代表和的最小值。
示例1
输入
5 3
2 4 8 10 11
输出
24
思路:先求和,将偶数都加入优先队列,每次取最大的偶数除以2,如果还是偶数就将它继续加入优先队列。维护最大偶数,当没有偶数或已操作m次时退出循环,此时和最小。
AC代码
#include<bits/stdc++.h>
using namespace std;
inline char getc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
int sca()
{
int su=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c))su=su*10+c-'0',c=getchar();
return su*f;
}
int main()
{
int n,m,x;
n=sca();m=sca();
priority_queue<int>p;
long long su=0;
for(int i=1;i<=n;++i)
{
x=sca();
if(x%2==0)
p.push(x);
su+=x;
}
while(!p.empty()&&m--)
{
int te=p.top()/2;
p.pop();
if(te%2==0)//将偶数加入优先队列,维护最大的偶数
p.push(te);
su-=te;//每次减少偶数的一半
}
printf("%lld\n",su);
}

京公网安备 11010502036488号