C. New Game (二分)

Posted on   Capterlliar  阅读(10)  评论(0编辑  收藏  举报

时隔多年又做题了这不得来水一篇博客

题意:给出n个数,取一段连续的数字,最大数和最小数的差不超过k,使得取的数最多。

解:对于每一个数,找到第最后一个连续的且与其差值不大于k的数,数一数期间一共有几个,然后取最大值。实现上先处理出连续的段,对于每一个数,找到对应的段,二分找出差值不大于k的数即可。

代码:

复制代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxx 200005
#define inf 1000000009
int n, k;
int a[maxx] = {0};
int sum[maxx] = {0};
int pre[maxx] = {0};

signed main(){
    int T;
    scanf("%d", &T);
    while (T--){
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
        }
        sort(a + 1, a + n + 1);
        a[n+1]=inf;
        sum[1] = 1;
        pre[1]=1;
        int now=1;
        pre[n]=n;
        for(int i=n-1;i>0;i--) {
            if (a[i+1] >= a[i] + 2){
                pre[i] = i;
            }
            else
                pre[i] = pre[i + 1];
        }
        int ans = 1;
        // for(int i=1;i<=n;i++) printf("%d ",a[i]); printf("\n");
        // for(int i=1;i<=n;i++) printf("%d ",sum[i]); printf("\n");
        // for(int i=1;i<=n;i++) printf("%d ",pre[i]); printf("\n");
        for(int i=1;i<=n;i++) {
            int l=i,r=pre[i],mid;
            // printf("%d\n",r);
            int ans1=l;
            while(l<=r){
                mid=l+(r-l)/2;
                if(a[mid] - a[i] + 1 <= k){
                    ans1=mid;
                    l=mid+1;
                }
                else
                    r=mid-1;
            }  
            // printf("%d ",ans1);
            ans = max(ans, ans1 - i + 1);
        }
        // printf("\n");
        printf("%d\n", ans);
    }
}
View Code
复制代码

 

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
历史上的今天:
2022-10-18 P1772 [ZJOI2006] 物流运输
点击右上角即可分享
微信分享提示