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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6383

 

题目就是让你求一个整数数组,在进行任意元素 + 1、 - 2 操作后,请问在所有可能达到的稳定数组中,拥有最大的『数组中的最小值』的那些数组,此值是多少呢?稳定数组是指数组中最大值 - 最小值 <= 1。

Sample Input

2
3
1 2 4
2
0 100000000
 

Sample Output

2
33333333
 
又想起那句“最大最小我tm一看就是二分”,然鹅知道是二分还是一脸懵逼QAQ
 

 做法还是二分答案,怎么判断答案是否满足要求呢?让比答案小的数 + 1,比答案大的数 - 2,正解满足 + 1的数比 - 2的数多或者相等,如果不满足这个条件的话答案就不是数组中的最小值了。这里有一个坑点,就是在算 - 2的数有几个时一定要每加一个数 / 2,而不要算出num2之后再 / 2,因为这里存在奇数和偶数,仔细想想还是能明白的(在这里wa了2次 - -、)

#include <bits/stdc++.h>
using namespace std;
const int N = 300005;
typedef long long LL;
LL a[N];
LL n;
bool ok(LL x)
{
    LL num1 = 0, num2 = 0;
    for(LL i = 0; a[i] < x; i++)
    {
        num1 = num1 + (x - a[i]);//+1的个数
    }
    for(LL i = n - 1; a[i] > x; i--)
    {
        num2 = num2 + (a[i] - x) / 2;//-2的个数
    }
    if(num2 >= num1) return 1;
    return 0;
}
int main()
{
    LL t;
    cin>>t;
    //freopen("1.txt", "w", stdout);
    while(t--)
    {
        scanf("%lld", &n);
        for(LL i = 0; i < n; i++)
        {
            scanf("%lld", &a[i]);
        }
        sort(a, a+n);
        LL l = a[0], r = a[n-1];
        while(l <= r)
        {
            LL mid = (l+r) >> 1;
            if(ok(mid))
                l = mid + 1;
            else
                r = mid - 1;
        }
        printf("%lld\n", r);
    }
}
posted @ 2018-08-13 17:06  LesRoad  阅读(259)  评论(0编辑  收藏  举报