20181029noip模拟赛T1
1、借书
【问题描述】
Dilhao一共有n本教科书,每本教科书都有一个难度值,他每次出题的时候都会从其中挑两本教科书作为借鉴,如果这两本书的难度相差越大,Dilhao出的题就会越复杂,也就是说,一道题的复杂程度等于两本书难度差的绝对值。
这次轮到ldxxx出题啦,他想要管Dilhao借m本书作为参考去出题,Dilhao想知道,如果ldxxx在Dilhao给出的m本书里挑选难度相差最小的两本书出题,那么ldxxx出的题复杂程度最大是多少?
【输入格式】
第一行是n和m。
接下来的n行,每行一个整数ai表示第i本书的难度。
【输入格式】
一个整数为ldxxx出的题复杂程度的最大值。
【输入样例】
6 3
5
7
1
17
13
10
【输出样例】
7
【样例解释】
Dilhao给了ldxxx难度为1,10,17的三本书,ldxxx挑选难度为10和17的两本书,出题复杂度为7;
如果Dilhao给出其他任何三本书,其中的两本书难度差的最小值都小于7,所以ldxxx出题最大的复杂程度为7。
【数据说明】
对于 30%的数据: 2<=n<=20;
对于 60%的数据: 2<=n<=1000;
对于 100%的数据: 2<=n<=100000, 2<=m<=n, 0<=ai<=1000000000。
思路:
一眼题
对于原数组,我们可以将它差分
然后二分一个答案出来
扫一遍原序列验证即可
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define rii register int i #define rij register int j using namespace std; int n,m,x[100005],cha[100005]; bool cmp(int lk,int kl) { return lk<kl; } bool check(int val) { int jsq=0,ch=0; for(rii=1;i<n;i++) { ch+=cha[i]; if(ch>=val) { jsq++,ch=0; } } if(jsq>=m-1) { return true; } return false; } int main() { freopen("margin.in","r",stdin); freopen("margin.out","w",stdout); scanf("%d%d",&n,&m); int r=0,l=0; for(rii=1;i<=n;i++) { scanf("%d",&x[i]); r=max(r,x[i]); } sort(x+1,x+n+1,cmp); for(rii=1;i<n;i++) { cha[i]=x[i+1]-x[i]; } while(l<=r) { if(r-l==1) { if(check(r)==true) { l=r; } break; } int mid=(l+r)/2; if(check(mid)==true) { l=mid; } else { r=mid; } } cout<<l; }