hdu 6383

题意是说给定一个序列,能否通过任意次对部分数字 +1,对部分数字 -2的操作使得序列在满足全部非负且任意两元素的差值不超过1的前提下最小值最大,求最大值。

一开始的时候没有注意到整个序列全是非负数,还写了一步判断是否所有正数都有能力将所有负数变正,也就是说所有正数的和是否为负数和的绝对值的两倍......

后来发现序列中没有负数,根本不会出现题目里所说的要输出 -1 的情况.....(至于都是正数为什么就能通过调整满足题中任意两元素差值不超过1这一点,我只能说这是我试了几次得到的结果,才疏学浅,没有能力严谨地去证明).

然后本人的做法是记录整个序列的最小和最大值,显然答案在最小值和最大值之间,用二分的方法调整 mid 的值:

当发现 mid 的值较小,也就是说所有大于 mid 的数仍有提高序列最小值的能力(同时要满足题意),那么就令 l = mid +1;若 mid 的值较大,所有大于 mid 的数无法通过减小自身来提高较小的数时, 则令 r = mid - 1。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 __int64 num[300005];
 4 int main()
 5 {
 6     int k;
 7     __int64 r,l,mid,temp;
 8     scanf("%d",&k);
 9     while(k--)
10     {
11         int n;
12         scanf("%d",&n);
13         r = 0; l = 1e8;
14         for(int i = 1; i <= n; i++)
15         {
16             scanf("%I64d",&num[i]);
17             r = max(r,num[i]);
18             l = min(l,num[i]);
19         }
20         while(r >= l)
21         {
22             mid = (r + l) / 2;
23             temp = 0;
24             for(int i = 1; i <= n; i++)
25                 if(num[i] - mid > 0)    temp += (num[i] - mid) / 2;
26                 else    temp += num[i] - mid;
27             if(temp >= 0)   l = mid + 1;
28             else    r = mid - 1;
29         }
30         printf("%d
",r);
31     }
32     return 0;
33 }
View Code
日后若能有更好的想法,再来完善。 希望看到的大神不吝赐教 orz
原文地址:https://www.cnblogs.com/Taskr212/p/9463330.html