1725. 【10.6NOIP普及模拟】MATH(math.pas/cpp)
(File IO): input:math.in output:math.out
时间限制: 1000 ms 空间限制: 256000 KB 具体限制
题目描述
小x正在做他的数学作业,可是作业实在太难了。题目是这样的:
1.给定一个含有N个数的数列V。
2.你可以从数列中恰好移除K个数,定义移除后的数列为V’。
3.定义M为V’中任意两个数的差的最大值,m为V’中任意两个数的差的最小值。
4.请你选择删去的K个数,使得M+m最小。
小x的数学十分之差,于是他只能向你求助了。
输入
第一行两个整数N和K。
第二行N个整数Vi。
输出
一行一个整数,为最小的M+m的和。
样例输入
5 2 -3 -2 3 8 6
样例输出
7
数据范围限制
对于60%的数据:3 ≤ N ≤ 2 000
对于100%的数据:
3 ≤ N ≤ 200 000
1 ≤ K ≤ N - 2
-5 000 000 ≤Vi ≤ 5 000 000
提示
【样例解释】
删去-3和-2,得到V’={3,6,8},M=5,m=2,M+m=7。
这题可以反着来想:
因为要删掉k个数,那么就会剩下n-k个数;所以我们只需要枚举这n-k个数即可;
qsort完之后,
可以发现,这n-k个数只有在排完序之后连续时才能使m尽可能最小,所以枚举区间,先枚举开始点,推出结束点,寻找最小n,寻找时如果前面找到最小的n在开始点之前,就重新找,否则可以直接把n和(新出来的结束点与上一个结束点的差)比较更新,计算ans
{ by @bobble ! 2017-1-19 } program math; const inf=‘math.in‘; outf=‘math.out‘; var n,k,i,min,ans,sp,ep,mp:Longint; a,c:array[1..200000] of longint; procedure qsort(l,r:longint); var i,j,x,y:longint; begin i:=l; j:=r; x:=a[(l+r) div 2]; repeat while a[i]<x do inc(i); while x<a[j] do dec(j); if not(i>j) then begin y:=a[i]; a[i]:=a[j]; a[j]:=y; inc(i); j:=j-1; end; until i>j; if l<j then qsort(l,j); if i<r then qsort(i,r); end; begin assign(input,inf); assign(output,outf); reset(input); rewrite(output); readln(n,k); for i:= 1 to n do read(a[i]); qsort(1,n); for i:= 1 to n-1 do c[i]:=a[i+1]-a[i]; mp:=0; ans:=maxlongint; for sp:= 1 to n-(n-k)+1 do //sp=start_point; begin ep:=sp+n-k-1;//end_point if mp<sp then begin min:=maxlongint; for i:= sp to ep-1 do if c[i]<min then begin min:=c[i];//min=min_cha mp:=i; //mp=min_piont end; end else if c[ep-1]<c[mp] then mp:=ep-1; if ans>a[ep]-a[sp]+c[mp] then ans:=a[ep]-a[sp]+c[mp]; //c[ep]-c[sp]=max!! end; writeln(ans); close(input); close(output); end.
时间: 2025-01-18 23:31:36