C++--取尺法/前缀和

取尺法

题目->NEFU OJ 2124

列举两种方法,都需要用到前缀和

方法一:遍历前缀和

#include 
using namespace std;
int a[100005];
int s[100005];
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    //priority_queue,greater >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 
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;
}

你可能感兴趣的:(笔记)