RAZLIKA
Description
Mirko's newest math homework assignment is a very difficult one! Given a sequence, V, of N integers,
remove exactly K of them from the sequence. Let M be the largest difference of any two remaining
numbers in the sequence, and m the smallest such difference. Select the K integers to be removed from
V in such a way that the sum M + m is the smallest possible. Mirko isn't very good at math, so he has
asked you to help him!
Input
The first line of input contains two positive integers, N (3 ≤ N ≤ 1 000 000) and K (1 ≤ K ≤ N - 2).
The second line of input contains N space-separated positive integers – the sequence V (-5 000 000 ≤
Vi ≤ 5 000 000).
Output
The first and only line of output must contain the smallest possible sum M + m
Sample Input
5 2 -3 -2 3 8 6
Sample Output
7
// 题目要求的是取出n-k个数,这些数的最大元素差+最小元素差 最小
// 这里明显是先排序,然后取其中的n-k个数,
// 我们可以枚举结尾 i ,这里先要预处理求出以 i 结尾的前n-k 个数之间的最小值、
#include <cstdio>
#include <algorithm>
#include<ctime>
#include <cstring>
#include<iostream>
#include<cmath>
#include<stack>
#define maxn 1000010
#define INF 30000000
#define LL long long
#define mod 100007
#define pi acos(-1.0)100099
using namespace std ;
#pragma comment(linker,"/STACK:102400000,102400000")
int a[maxn] ;
int min1[maxn][2] ,min2[maxn][2] ;
//min1[i][0] 保存的是以i结尾的前k个数两着之间的最小值,min2[i][0]是次小值
//min1[i][1] 是取得最小值时它的位置
int main()
{
int j , len , i , k ,jj ;
int n , ans, m ;
//freopen("in.txt","r",stdin) ;
while( scanf("%d%d" , &n ,&k ) != EOF )
{
ans = INF ;
for( i = 1 ; i <= n ; i++ )
scanf("%d" , &a[i]) ;
sort(a+1,a+1+n) ;
min1[1][0] = INF ;min2[2][0] = INF ;
min2[1][0] = INF ;min1[2][0] = a[2]-a[1] ;
min1[2][1] = 1 ;min2[1][0] = 1 ;
k = n-k ;
for( i = 3 ; i <= n ;i++ )
{
j = min1[i-1][1];
jj = min2[i-1][1] ;
if( i - j >= k || i - jj >= k )
{
if(i-j >= k)
{
if( a[i]-a[i-1] <= min2[i-1][0] )
{
min1[i][0] = a[i]-a[i-1] ;
min1[i][1] = i-1 ;
min2[i][0] = min2[i-1][0];
min2[i][1] = min2[i-1][1] ;
}
else
{
min1[i][0] = min2[i-1][0] ;
min1[i][1] = min2[i-1][1] ;
min2[i][0] = a[i]-a[i-1] ;
min2[i][1] = i-1 ;
}
}
else if(i-jj >= k)
{
if(a[i]-a[i-1] <= min1[i-1][0])
{
min2[i][0] = min1[i-1][0];
min2[i][1] = min1[i-1][1];
min1[i][0] = a[i]-a[i-1] ;
min1[i][1] = i-1 ;
}
else
{
min2[i][0] = a[i]-a[i-1] ;
min2[i][1] = i-1 ;
min1[i][0] = min1[i-1][0];
min1[i][1] = min1[i-1][1];
}
}
}
else
{
if(a[i]-a[i-1] <= min1[i-1][0])
{
min2[i][0] = min1[i-1][0];
min2[i][1] = min1[i-1][1];
min1[i][0] = a[i]-a[i-1] ;
min1[i][1] = i-1 ;
}
else if( a[i]-a[i-1] <= min2[i-1][0] )
{
min2[i][0] = a[i]-a[i-1];
min2[i][1] = i-1;
min1[i][0] = min1[i-1][0] ;
min1[i][1] = min1[i-1][1] ;
}
else
{
min1[i][0] = min1[i-1][0] ;
min1[i][1] = min1[i-1][1] ;
min2[i][0] = min2[i-1][0] ;
min2[i][1] = min2[i-1][1] ;
}
}
}
//枚举结尾
for( i = k ; i <= n ;i++ )
{
jj = a[i]-a[i-k+1] ;
if(jj+min1[i][0] < ans )
ans = jj+min1[i][0] ;
}
printf("%d\n",ans) ;
}
return 0 ;
}
7
// 题目要求的是取出n-k个数,这些数的最大元素差+最小元素差 最小
// 这里明显是先排序,然后取其中的n-k个数,
// 我们可以枚举结尾 i ,这里先要预处理求出以 i 结尾的前n-k 个数之间的最小值、
#include <cstdio>
#include <algorithm>
#include<ctime>
#include <cstring>
#include<iostream>
#include<cmath>
#include<stack>
#define maxn 1000010
#define INF 30000000
#define LL long long
#define mod 100007
#define pi acos(-1.0)100099
using namespace std ;
#pragma comment(linker,"/STACK:102400000,102400000")
int a[maxn] ;
int min1[maxn][2] ,min2[maxn][2] ;
//min1[i][0] 保存的是以i结尾的前k个数两着之间的最小值,min2[i][0]是次小值
//min1[i][1] 是取得最小值时它的位置
int main()
{
int j , len , i , k ,jj ;
int n , ans, m ;
//freopen("in.txt","r",stdin) ;
while( scanf("%d%d" , &n ,&k ) != EOF )
{
ans = INF ;
for( i = 1 ; i <= n ; i++ )
scanf("%d" , &a[i]) ;
sort(a+1,a+1+n) ;
min1[1][0] = INF ;min2[2][0] = INF ;
min2[1][0] = INF ;min1[2][0] = a[2]-a[1] ;
min1[2][1] = 1 ;min2[1][0] = 1 ;
k = n-k ;
for( i = 3 ; i <= n ;i++ )
{
j = min1[i-1][1];
jj = min2[i-1][1] ;
if( i - j >= k || i - jj >= k )
{
if(i-j >= k)
{
if( a[i]-a[i-1] <= min2[i-1][0] )
{
min1[i][0] = a[i]-a[i-1] ;
min1[i][1] = i-1 ;
min2[i][0] = min2[i-1][0];
min2[i][1] = min2[i-1][1] ;
}
else
{
min1[i][0] = min2[i-1][0] ;
min1[i][1] = min2[i-1][1] ;
min2[i][0] = a[i]-a[i-1] ;
min2[i][1] = i-1 ;
}
}
else if(i-jj >= k)
{
if(a[i]-a[i-1] <= min1[i-1][0])
{
min2[i][0] = min1[i-1][0];
min2[i][1] = min1[i-1][1];
min1[i][0] = a[i]-a[i-1] ;
min1[i][1] = i-1 ;
}
else
{
min2[i][0] = a[i]-a[i-1] ;
min2[i][1] = i-1 ;
min1[i][0] = min1[i-1][0];
min1[i][1] = min1[i-1][1];
}
}
}
else
{
if(a[i]-a[i-1] <= min1[i-1][0])
{
min2[i][0] = min1[i-1][0];
min2[i][1] = min1[i-1][1];
min1[i][0] = a[i]-a[i-1] ;
min1[i][1] = i-1 ;
}
else if( a[i]-a[i-1] <= min2[i-1][0] )
{
min2[i][0] = a[i]-a[i-1];
min2[i][1] = i-1;
min1[i][0] = min1[i-1][0] ;
min1[i][1] = min1[i-1][1] ;
}
else
{
min1[i][0] = min1[i-1][0] ;
min1[i][1] = min1[i-1][1] ;
min2[i][0] = min2[i-1][0] ;
min2[i][1] = min2[i-1][1] ;
}
}
}
//枚举结尾
for( i = k ; i <= n ;i++ )
{
jj = a[i]-a[i-k+1] ;
if(jj+min1[i][0] < ans )
ans = jj+min1[i][0] ;
}
printf("%d\n",ans) ;
}
return 0 ;
}