度度熊很喜欢数组!!
我们称一个整数数组为稳定的,若且唯若其同时符合以下两个条件:
1. 数组里面的元素都是非负整数。
2. 数组里面最大的元素跟最小的元素的差值不超过 11。
举例而言,[1,2,1,2][1,2,1,2] 是稳定的,而 [−1,0,−1][−1,0,−1] 跟 [1,2,3][1,2,3] 都不是。
现在,定义一个在整数数组进行的操作:
* 选择数组中两个不同的元素 aa 以及 bb,将 aa 减去 22,以及将 bb 加上 11。
举例而言,[1,2,3][1,2,3] 经过一次操作后,有可能变为 [−1,2,4][−1,2,4] 或 [2,2,1][2,2,1]。
现在给定一个整数数组,在任意进行操作后,请问在所有可能达到的稳定数组中,拥有最大的『数组中的最小值』的那些数组,此值是多少呢?
Input
输入的第一行有一个正整数 TT,代表接下来有几组测试数据。
对于每组测试数据:
第一行有一个正整数 NN。
接下来的一行有 NN 个非负整数 xixi,代表给定的数组。
* 1≤N≤3×1051≤N≤3×105
* 0≤xi≤1080≤xi≤108
* 1≤T≤181≤T≤18
* 至多 11 组测试数据中的 N>30000N>30000
Output
对于每一组测试数据,请依序各自在一行内输出一个整数,代表可能到达的平衡状态中最大的『数组中的最小值』,如果无法达成平衡状态,则输出 −1−1。
Sample Input
2 3 1 2 4 2 0 100000000
Sample Output
2 33333333
这道题一开始题意都理解不好,尤其是那个“代表可能到达的平衡状态中最大的『数组中的最小值』”,这么绕口。。。
好了,不吐槽了
其实就是让你找平衡状态时,数组中的最小值,达到平衡时数组中也就俩数,因为要保证最大值最小值之差小于1
解题的思路是这样的,总体上是用的二分法,先找出数组中的中间值,接着遍历数组中的每个元素,如果小于数组,x加上这个差,如果大于数组,y加上这个差的一半;最后比较这两个数的大小,就是二分的步骤。
大概就是这样,要加把劲了
补充一个小知识点:
关于%I64d和%lld的问题
两种都是C语言中格式化输出64位整型的正确做法。
区别在于编译器不同。
gcc(mingw32),g++(mingw32)只支持%I64d的输出方式。
gcc(linux i386),g++(linux i386)只支持%lld的输出方式。
另外,mac上的gcc/g++不支持%I64d的方式。
最后把代码码一遍吧
#include<iostream>
#include<stdio.h>
#define maxn 300010
#define LL long long
LL a[maxn];
using namespace std;
int main(){
int N;
cin>>N;
while(N--){
LL T;
cin>>T;
for(int i=0;i<T;i++){
cin>>a[i];
}
LL mid;
LL l=0;
LL r=0;
while(l+1<r){
l=a[0];
r=a[0];
for(int i=0;i<T;i++){
if(l>a[i]){
l=a[i];
}
if(r<a[i]){
r=a[i];
}
}
mid=(l+r)/2;
LL x=0;
LL y=0;
for(int i=0;i<T;i++){
if(a[i]<mid){
x+=mid-a[i];
}else{
y+=(a[i]-mid)/(LL)2;
}
}
if(x>=y){
l=mid;
}else{
r=mid;
}
}
printf("%l64d",l);
}
}