HDU-6383

题目:

度度熊很喜欢数组!!

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

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

A为原数列,A*为由A变化成的稳定数列,那么题目所求的就是 所有A*中的最小值最大的一个,把这个值记为ans

首先可以先考虑能不能直接暴力枚举所有A*,然后求解...... 很明显是不符合实际的。

换种想法,能不能让ans从无穷大遍历到0,暴力枚举所有ans,然后判断这个ans是否可以构成A*。

那么要先解决判断的问题。

题目要求的是:* 选择数组中两个不同的元素 a 以及 b,将 a 减去 2,以及将 b 加上 1。(这里“不同”指的是下标不同)

也就是进行一次减法(-2),必须要进行一次加法(+1),两种操作的次数要相等。那么可以分开操作,然后再来看两种操作的次数。

我们先对原数列A中所有小于ans的数A[i],做加法,num_p += ans - A[i]

然后对原数列A中所有大于ans+1的数A[i],做减法,num_m += (A[i] - ans) / 2

这里可能会出现A[i] - ans 是奇数的情况,如:(A[i] - ans) / 2 = 3 / 2 = 1,那么其实这时候,A[i]做完减法后得到的数应该是ans+1,它可以作为这个数列A*的最大值,使得数列A*仍然满足 “稳定” 的条件。(min:ans,max:ans+1)

接下来要对num_p(进行加法的次数)和 num_m(进行减法的次数)做比较:

num_p = num_m 的情况:说明这个ans可以作为稳定数列A*的最小值。
num_p != num_m 的情况:

首先要了解的一点是:

对于一个数列A,如果它的最小值为min(A),那么它可以通过题目所述的两种操作,来得到一个稳定数组A*,其最小值仍为min(A)。具体做法是:我们更新数组A,将A中最小值+1,最大值-2,不断重复这个过程。由于减掉的比加上的多,最终数组A中的最大最小值会不断地相互逼近,直到最小值为min(A)。

那么对于num_p < num_m:此时当加法减法配对后,仍有一些数需要进行减法操作,也就是说,此时的数列A最小值已经是ans了,存在一些数大于ans+1,那么根据上面的结论,这个数列A是可以得到稳定数组的,所以这个ans合法。

对于num_p > num_m :此时当加法减法配对后,仍有一些数需要进行加法操作,由于我们进行的是-2,+1,也就是总的来说肯定是朝减少的方向进行,既然出现还要加上的操作,只能说明这个ans还太大了,满足不了,得不到稳定数组。

解决完判断的问题,剩下的就是对ans的范围从原先的 0~∞ 进一步缩减。

很明显的上界应当为数列A的最大值max(A):倘若大于max(A)的话,那么A中所有的数都要往上加才行,由于有减法操作,实现不了;

下界应当为数列A的最小值min(A):在前面红色的结论已经说明了,ans至少会等于min(A)。

那么可以看出采用的算法应该是二分法,边界:min(A)~ max(A)

代码:

//
//  main.cpp
//  初赛B1004
//
//  Created by jinyu on 2018/8/13.
//  Copyright © 2018年 jinyu. All rights reserved.
//#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;typedef long long  LL;
const int MAXN = 3e5+7;
const long long INF = 0x3f3f3f3f3f3f;long long A[MAXN];
int N;bool judge(LL ans){LL num_p = 0;LL num_m = 0;for(int i = 0;i<N;++i){if(ans > A[i])num_p += ans-A[i];else if(ans+1 < A[i])num_m += (A[i]-ans)/2;}return num_m>=num_p;
}int main(){int T;scanf("%d",&T);while (T--) {scanf("%d",&N);LL R = -1;LL L = INF;for(int i = 0;i<N;++i)scanf("%lld",&A[i]);sort(A,A+N);L = A[0];R = A[N-1];LL ans = -1;while(L<=R){LL mid = (L+R)/2;if(judge(mid)){L = mid + 1;ans = mid;}elseR = mid - 1;}printf("%lld\n",ans);}return 0;
}

2018百度之星程序设计大赛初赛B——1004p1m2相关推荐

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

    p1m2 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Sub ...

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

    degree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

  3. hdu6375(2018 “百度之星”程序设计大赛 - 初赛(A))

    度度熊学队列 Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

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

    hdu6374                         度度熊拼三角 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536 ...

  5. 2018 “百度之星”程序设计大赛 - 初赛(A)P1002度度熊学队列(双端队列模拟,STL)

    problem 度度熊正在学习双端队列,他对其翻转和合并产生了很大的兴趣. 初始时有 N 个空的双端队列(编号为 1 到 N ),你要支持度度熊的 Q 次操作. ①1 u w val 在编号为 u 的 ...

  6. 2018 “百度之星”程序设计大赛 - 初赛(A)P1001度度熊拼三角(贪心)

    problem 给定n根棍子.在其中选三根拼成最大周长三角形的周长.不能拼出三角形输出-1. solution 先对数组进行排序,并利用贪心算法先取得最长的一根棍子,之后的两根依次取最长的棍子,如果这 ...

  7. 2018 “百度之星”程序设计大赛 - 初赛(B)Pro.1001 degree

    题目链接 至多删k条边,自由添边保证无环,求最大度数. 找出度数最大的度数值ans,再利用并查集求出集合数sum,加k时判断是否大于n-1即可. #include<cstdio> #inc ...

  8. 【2018百度之星程序设计大赛初赛】rect

    Problem Description 度度熊有一个大小为 MX×MYMX×MYMX \times MY 的矩形,左下角坐标为 (0,0)(0,0)(0, 0),右上角坐标为 (MX,MY)(MX,M ...

  9. HDU 6114 Chess 【组合数】(2017百度之星程序设计大赛 - 初赛(B))

    Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  10. 2018百度之星程序设计大赛 - 资格赛 hdu6345(找区间最小值)

    子串查询 Time Limit: 3500/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Sub ...

最新文章

  1. ASP.NET 应用程序生命周期概述
  2. java7 的final真的有坑啊。
  3. Java机器学习库ML之一Dataset和Instance
  4. 【Paper】2017_水下潜航器编队海洋勘测的协调控制方法研究
  5. RMAN深入解析之--控制文件
  6. Javadoc的Html文件传输chm
  7. perl 哈希数组的哈希_第一个元素使用哈希在数组中出现K次
  8. labiview ni python_LabVIEW到底有哪些优势导致他用户量这么少但是长期不消失?
  9. word无法验证服务器,windows10系统下office2010无法验证的解决方法
  10. XCode出现Could not locate device support files的解决办法
  11. matlab朴素贝叶斯手写数字识别_「深度学习系列」PaddlePaddle之手写数字识别
  12. 人口预测模型基础介绍
  13. Unity利用SMSSDK实现短信验证码(附源代码)
  14. 冒泡详解(分析每一步)
  15. Android选择DNK出现“NDK does not contain any platforms”
  16. Linux运维工程师综合面试题
  17. 杂谈:WiFi包和buffer
  18. 小米路由pro php,家庭实测 | 荣耀路由Pro2 可以吊打小米路由器吗?
  19. 认证管理(锐捷网关篇)
  20. 数字孪生医院的智能化运营平台建设内容

热门文章

  1. Android Socket通信
  2. Alex 的 Hadoop 菜鸟教程: 第7课 Hbase 使用教程
  3. 用Python实现简单的人脸识别,10分钟搞定!(附源码)
  4. matlab r2008a下载,Matlab+R2008a下载地址及安装教程
  5. 个人账目管理系统oracle,个人账务管理系统(论文).doc
  6. 频段、信道带宽、EARFCN、频段和EARFCN之间的换算
  7. excel随机数_Excel小技巧之随机数表
  8. 图像识别的工作原理是什么?商业上如何使用它?
  9. 实战总结的7个C程序,好东西不私藏
  10. Spring定时器的时间表达式 定时器的时间表达式: