兔崽小孩(stl二分查找upper/lower_bound,前缀和,优化)(2022牛客寒假算法基础集训营5)

题目:兔崽小孩

预备知识:

stl中的二分查找函数:

upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)返回一个非递减序列[first, last)中第一个大于val的位置,返回值为指针,ForwardIter first为数组元素首地址,ForwardIter last为数组元素尾地址的后一个地址。
lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)返回一个非递减序列[first, last)中的第一个大于等于值val的位置。
binary_search( first, last, value ,(cmp) )在已排序的[first,last) 前闭后开 区间中寻找元素value,若存在就返回true,若不存在则返回false 。

先用一个d[i]数组存放每一段休息时长,对d数组进行排序,用d数组的前缀和sum[i]存放前i段休息时长,然后对d数组二分查找,找到单段休息时长大于k的数组下标后直接用公式(休息时长=最大时长-前i-1段的时长-剩余段数*k)求出叉同学的睡觉时长。

这题用cin,cout居然wa了,于是改用scanf和printf。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int n, q;
int d[maxn];//每段休息时长
ll sum[maxn];//前i段休息时长
int main()
{
	scanf("%d %d", &n, &q);
	int x, temp;
	scanf("%d", &x);
	for (int i = 1; i < n; i++) {
		scanf("%d", &temp);
		d[i] = temp - x;//每段休息时长存入d数组(不考虑入睡时长)
		x = temp;
	}
	sort(d + 1, d + n);
	for (int i = 1; i < n; i++) {
		sum[i] = sum[i - 1] + d[i];//求前缀和
	}
	while (q--) {
		int k, p;
		scanf("%d %d", &k, &p);
		int i = upper_bound(d + 1, d + n, k) - d;//二分查找
		ll ans = sum[n - 1] - sum[i - 1] - (n - i) * k;//休息时长=最大时长-前i-1段的时长-剩余段数*k
		if (ans >= p) printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值