取尺法
题目->NEFU OJ 2124
列举两种方法,都需要用到前缀和
方法一:遍历前缀和
#include <bits/stdc++.h>
using namespace std;
int a[100005];
int s[100005];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
//priority_queue<int,vector<int>,greater<int> >que;
int x;
int maxx=1;
for(int i=1; i<=n; i++)
{
scanf("%d",&x);
a[x]++;
if(x>maxx)
maxx=x;
}
s[0]=a[0];
for(int i=1;i<=maxx;i++)
{
s[i]=s[i-1]+a[i];
}
int ans;
if(k>maxx)
{
ans=n;
}
for(int i=0;i+k<=maxx;i++)
{
if(i==0)
{
ans=s[k];
}
else
{
ans=(s[k+i]-s[i-1])>ans?(s[k+i]-s[i-1]):ans;
}
}
printf("%d\n",ans);
return 0;
}
方法二:取尺法
#include <bits/stdc++.h>
using namespace std;
int vis[100005];
int sum[100005];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
vector<int>ve;
int x;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(!vis[x])
ve.push_back(x);
vis[x]++;
}
sort(ve.begin(),ve.end());
//cout << *(ve.begin()+1) << endl ;
sum[0]=0;
for(int i=0;i<ve.size();i++)
{
if(i==0)
{
sum[i]=vis[ve[i]];
}
else
{
sum[i]=sum[i-1]+vis[ve[i]];
}
}
//cout << sum[0] << sum[1] << sum[2] << sum[3] << endl ;
int l=0;
int maxx=0;
//sum[-1]=0; 这样写有风险,最好不要这样写
for(int r=0;r<ve.size();r++)
{
int t;
if(ve[r]-ve[l]<=k)
{
//t=sum[r]-(l-1>=0?sum[l-1]:0); 这样写和下面的是一样的
if(l-1>=0)
t=sum[r]-sum[l-1];
else
t=sum[r];
maxx=maxx>t?maxx:t;
continue;
}
else
{
while(ve[r]-ve[l]>k)
{
l++;
}
t=sum[r]-sum[l-1];
maxx=maxx>t?maxx:t;
}
}
printf("%d\n",maxx);
return 0;
}