p1m2 【二分】2018 “百度之星”程序设计大赛 - 初赛(B)

探讨了如何通过操作使数组达到稳定状态,并找到稳定状态下最大最小值的问题。使用二分查找来确定是否可以实现特定的最小值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://acm.hdu.edu.cn/showproblem.php?pid=6383

Problem Description

度度熊很喜欢数组!!

我们称一个整数数组为稳定的,若且唯若其同时符合以下两个条件:

1. 数组里面的元素都是非负整数。
2. 数组里面最大的元素跟最小的元素的差值不超过 1 。

举例而言,[1,2,1,2] 是稳定的,而 [−1,0,−1] 跟 [1,2,3] 都不是。

现在,定义一个在整数数组进行的操作:

* 选择数组中两个不同的元素 a 以及 b ,将 a 减去 2 ,以及将 b 加上 1 。

举例而言,[1,2,3] 经过一次操作后,有可能变为 [−1,2,4] 或 [2,2,1] 。

现在给定一个整数数组,在任意进行操作后,请问在所有可能达到的稳定数组中,拥有最大的『数组中的最小值』的那些数组,此值是多少呢?

 

 

Input

输入的第一行有一个正整数 T ,代表接下来有几组测试数据。

对于每组测试数据:
第一行有一个正整数 N 。
接下来的一行有 N 个非负整数 xi ,代表给定的数组。

* 1≤N≤3×105
* 0≤xi≤108
* 1≤T≤18
* 至多 1 组测试数据中的 N>30000

 

 

Output

对于每一组测试数据,请依序各自在一行内输出一个整数,代表可能到达的平衡状态中最大的『数组中的最小值』,如果无法达成平衡状态,则输出 −1 。

 

 

Sample Input

 

2 3 1 2 4 2 0 100000000

 

 

Sample Output

 

2 33333333

 

 

Source

2018 “百度之星”程序设计大赛 - 初赛(B)

 

分析:
二分查找答案,只要cc>=aa,这个数肯定能实现x为平衡数组的最小值,但不一定是最大的,所以要让l=mid+1。。(一定记得要long long )

代码:

#include<bits/stdc++.h>
using namespace std;
long long int n;
long long a[301005];
struct node
{
    long long int id,numm;
};
long long int go(long long int x)
{
    long long int aa,bb,cc,i,j,num,num2;//aa为小于 bb 为大1的个数  cc为远大的个数
    aa=bb=cc=0;
    long long flag;
    flag=0;
    num=0;
    for(i=1;i<=n;i++)
    {
        if(a[i]<x)
        {
            aa+=(x-a[i]);
        }
        else
        if(a[i]==x)
        num=i;
        else
        if(a[i]>x+1)
        {
            cc+=(a[i]-x)/2;
            if((a[i]-x)%2==0)bb++;
            else
                flag=1;
        }
    }
    if(aa>cc)
        return 1;
    return 0;
}
int main()
{
    long long  tt,i,j,l,r,mid,maxn,ans,ok;
    scanf("%lld",&tt);
    while(tt--)
    {
        scanf("%lld",&n);
        maxn=0;
        for(i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
        }
        sort(a+1,a+n+1);
        l=a[1];
        ans=a[n];
        r=a[n];
        while(l<=r)
        {
            mid=(l+r)>>1;
            ok=go(mid);
            if(ok==0)
                ans=mid,l=mid+1;
            else
                r=mid-1;
        }
        printf("%lld\n",ans);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值