# CF1891C Smilo and Monsters
题目链接
# 题目大意
给出一个长度为 的数组 ,你可以进行以下两个操作
将其中任意一个数的值减少 ,并使你的计数器 ,
将其中任意一个数的值减少 ,并使你的计数器 归零
求使一个数组所有元素归零的最小操作数
# 思路
不难发现,我们可以先把数组中较小的数用第一个操作归零,然后把数组中较大的数用第二个操作归零,这样做最大化利用 ,可以确保操作数是最小的
所以先将数组从小到大排序一下,用双指针 分别指向数组的头和尾,再按照贪心思路进行模拟即可
# 代码
#include<bits/stdc++.h> | |
#define int long long | |
#define in inline | |
#define ri register | |
#define _123hh2 0 | |
using namespace std; | |
in int read() | |
{ | |
int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();} | |
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}return x*f; | |
} | |
in void write(int x) {if(x<0) {x=-x;putchar('-');}if(x>9) write(x/10);putchar(x%10+'0');} | |
const int maxn=2e5+1; | |
int awa[maxn]; | |
signed main() | |
{ | |
int t=read(); | |
while(t-->0) | |
{ | |
int n=read(); | |
for(int i=1;i<=n;i++) awa[i]=read(); | |
sort(awa+1,awa+1+n); | |
int l=1,r=n,cnt=0,ans=0; | |
while(l<=r) | |
{ | |
if(l==r) | |
{ | |
if(!awa[l]) break; | |
if(!cnt) {ans+=awa[l]==1?1:(awa[l]+3)/2;break;} | |
else {ans+=(awa[l]-cnt+3)/2;break;} | |
} | |
if(cnt+awa[l]>=awa[r]) | |
{ | |
awa[l]-=awa[r]-cnt; | |
ans+=awa[r]-cnt+1,cnt=0,r--; | |
if(!awa[l]) l++; | |
} | |
else cnt+=awa[l],ans+=awa[l],l++; | |
} | |
write(ans),puts(""); | |
} | |
return _123hh2; | |
} |