原题链接:
题目解读:
给出一个长度为n的数组和一个整数k,对该数组删掉一些数,再对其进行任意顺序的排序,使得剩下的数组成的数组相邻两个数之间的绝对值之差不大于k,求最少需要删除的数字的个数.
算法实现:
先对数组进行升序排序,再依次枚举数组的前n-1项与其后一项的绝对值之差(因为是升序,所以可以简化为a[i+1]-a[i]),如果不大于k,则计数器cnt+1,否则先用max比较并记录下最大连续(即绝对值之差不大于k)的长度,再初始化计数器cnt=1,如果比较到数组最后两个数,也要将计数器与最大值max进行比较.最后输出n-max即为需要删除的最少的个数.
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2*100000 + 10;
int a[N];
void solve(){
int n, k,cnt=1,max=0;
cin >> n >> k;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a,a+n);
for (int i = 0; i <= n - 2; i++) {
if (a[i+1] - a[i] <= k)cnt++;//记录绝对值只差不大于k的数量
else if(a[i+1]-a[i]>k){//连续性断开了,需要判断一下,以便记录下最大连续的长度
if(cnt>max)
max=cnt;
cnt=1;
}
if(i==n-2){//最后的时候再判断一下
if(cnt>max){
max=cnt;
}
}
}
if(max==0)max=n;//全部的数都符合绝对值不大于k,应该输出0,这里为了统一输出语句,令max=n;
cout<<n-max<<endl;//总的个数n减去符合条件的个数,剩下的就是需要删除的
}
int main()
{
std::ios::sync_with_stdio(false);
int t; cin >> t;
while (t--) {
solve();
}
return 0;
}