codeforces 672 D
2016-07-27 10:41
218 查看
题目链接:http://codeforces.com/problemset/problem/672/D
题目大意:进行k次操作,每次将最大值集合中最大值-1,最小值+1,问你K次操作之后,最大值和最小值的差值是多少
思路分析:二分寻找最大值和最小值,check函数很好写,但是关键的一点需要注意,就是二分的上下限,当k非常大
时,最后的结果就已经稳定在平均数位置,如果二分上下限没有选对,就会出现最小值>最大值的情况orz
代码:
题目大意:进行k次操作,每次将最大值集合中最大值-1,最小值+1,问你K次操作之后,最大值和最小值的差值是多少
思路分析:二分寻找最大值和最小值,check函数很好写,但是关键的一点需要注意,就是二分的上下限,当k非常大
时,最后的结果就已经稳定在平均数位置,如果二分上下限没有选对,就会出现最小值>最大值的情况orz
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=500000+100; typedef long long ll; int a[maxn]; int n,k; int checkmi(int x) { ll sum=0; for(int i=0;i<n;i++) { if(a[i]>x) break; sum+=x-a[i]; } if(sum<=k) return 1; else return 0; } bool checkma(int x) { ll sum=0; for(int i=n-1;i>=0;i--) { if(a[i]<x) break; sum+=a[i]-x; } if(sum<=k) return 1; else return 0; } int main() { while(scanf("%d%d",&n,&k)!=EOF) { ll sum=0; for(int i=0;i<n;i++) {scanf("%d",&a[i]); sum+=a[i];} sort(a,a+n); int al,ar; if(sum%n==0) {al=sum/n,ar=sum/n;} else {al=sum/n,ar=sum/n+1;} int l=a[0],r=al; int ansl=a[0],ansr=a[0]; while(l<=r) { int mid=(l+r)>>1; if(checkmi(mid)) { ansl=mid; l=mid+1; } else r=mid-1; } l=ar,r=a[n-1]; while(l<=r) { int mid=(l+r)>>1; if(checkma(mid)) { ansr=mid; r=mid-1; } else l=mid+1; } printf("%d\n",ansr-ansl); } return 0; }
相关文章推荐
- 笔记8 Dialog常见类型及常用属性 自定义dialog
- 欢迎使用CSDN-markdown编辑器
- java 封装
- openfire 插件开发
- 如何提取谷歌地球的高程点为XYZ文本
- JavaScript强化教程 - 六步实现贪食蛇
- vfork()在使用过程中不能使用return 0
- Should we always favor xrange() over range()
- Java8一些新特性
- SQL中的cast()函数
- ProgressBar及其子类
- 廖雪峰JS教程学习记录----学习函数
- Git 使用相关
- 使用protobuf的反射来动态生成Message并赋值
- php 合并一个二维数组相同项,数量则相加
- 【codevs 1743】反转卡片 splay的应用
- hdu 3555 bomb 数位dp
- [树状数组] poj 2155 Matrix
- B树
- kafka源码分析之producer