兔崽小孩(排序+二分+前缀和)

本文介绍了一名程序员如何通过合理安排睡眠时间,避免因凌晨发说说而被教主刘骂到的算法问题。通过计算入睡和清醒时间,利用前缀和和二分查找技巧解决是否会被骂的判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:I-兔崽小孩_2022牛客寒假算法基础集训营5 (nowcoder.com)

题目:叉同学虽然是wf爷,但平时傻愣愣的,游戏也玩不过九峰,经常被九峰取笑。有一次叉同学熬夜看球并在凌晨四点半和五点半连发两条说说,被早起水群的刘教主看到了,骂他道:"兔崽子,你这是玩通宵啊,不要命啦"。从此叉同学凌晨发说说总是慎之又慎,避免被骂。

假设叉同学入睡需要k分钟,且他必须醒着才能发说说,刘教主早上醒来后发现他肯定没睡够p分钟就会骂他,叉同学想知道自己是否会被骂。

输入描述:

第一行一个正整数n,q,n,q,n,q,表示说说条数和询问个数

第二行nnn个正整数t1,t2,...,tn,t_1,t_2,...,t_n,t1​,t2​,...,tn​,表示nnn条说说的时间,保证ti<ti+1(i<n)t_i<t_{i+1}(i < n)ti​<ti+1​(i<n)

接下来qqq行每行一次询问,每行两个正整数k,p,k,p,k,p,表示叉同学的入睡需要时间和刘教主认为叉同学需要的睡眠时间

输出描述:

对于每次询问,如果叉同学不会被骂则输出一行"Yes",否则输出一行"No"(不包括双引号)

示例1

输入

复制5 2 1 2 5 9 10 3 1 3 2

5 2
1 2 5 9 10
3 1
3 2

输出

复制Yes No

Yes
No

说明

叉同学入睡需要3分钟,所以只可能在第3第4两条说说之间的4分钟间隔睡1分钟  

备注:

n,q≤106n,q \leq 10^6n,q≤106

ti≤109t_i \leq 10^9ti​≤109

k,p≤109k,p \leq 10^9k,p≤109

叉同学发第一条说说之前和发完最后一条说说之后视为一直醒着

 思路:先将发说说的间隔时间存下来,按照降序排序,做个前缀和,然后二分找到第一个小于等于k的位置,然后看前缀和-区间长度*k是否符合。

lower_bound(ans,ans+cnt,k,greater<int>())  (返回ans数组中第一个小于等于k的位置)

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[1000005],ans[1000005],sum[1000005];
bool cmp(int x,int y){ return x>y;}
signed main()
{//1716,1250964
    int n,q,cnt=0;
    scanf("%lld %lld",&n,&q);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    for(int i=2;i<=n;i++){
        ans[cnt++]=a[i]-a[i-1];
    }
    sort(ans,ans+cnt,cmp);
    sum[0]=ans[0];
    for(int i=1;i<cnt;i++) sum[i]=(ans[i]+sum[i-1]);
    while(q--){
        int k,p,res=0,i=0;
        scanf("%lld %lld",&k,&p);
        i=lower_bound(ans,ans+cnt,k,greater<int>())-ans-1;
        res=sum[i]-(i+1)*k;
        if(res>=p) printf("Yes\n");
        else printf("No\n");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值