2018 “百度之星”程序设计大赛 - 初赛(B)1004
典型的最大化最小值问题,二分解决。
注意:肯定有解,所以最小的解就是数组中最小的值。
二分的时候注意l和r的取值,不然会WA或出不来结果,在这里l=mid+1,r=mid。
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=300005;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
ll a[maxn],n,sum[maxn];
ll jud(int mid)
{
ll pos=n+1;
for(int i=1;i<=n;i++)
{
if(a[i]>mid)
{
pos=i;
break;
}
}
ll x,y=0;
for(int i=pos;i<=n;i++)
{
y+=(a[i]-mid)>>1; //计算减了多少2
}
x=mid*(pos-1)-sum[pos-1];//计算加了多少1
if(y<x)
{
return 0;
}
return 1;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int t;
cin>>t;
while(t--)
{
memset(sum,0,sizeof(sum));
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
sum[i]+=(sum[i-1]+a[i]);
}
ll l=a[1],r=a[n],ans=l;
while(l<r)
{
int mid=(r+l)>>1;
if(jud(mid))
{
l=mid+1;
ans=mid;
}
else
{
r=mid;
}
}
cout<<ans<<endl;
}
return 0;
}