第五维度(二分及前缀和)

码题集OJ-第五维度 (matiji.net)

经过昨天的折磨,今天写这个二分加前缀和真的得心应手,嘿嘿,小小得瑟一下。

我们首先用二分去枚举时间点,使用check去检查这个时间点是否能满足要求,即无论删除哪一个人始终在这个时间点下的贡献度之和都大于等于m,那么在这个时间点肯定是能达到五维世界的。

时间复杂度为O(NlogN)

#include<iostream>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=1e5+5;
int n,m;
//t代表一共有多少个科学家有理解力
int t=0;
PII arr[N];
//判断此时的年份是否可以提供足够的时间供人类理解五维
//即使是在任何一个人被抹杀的情况下
bool check(LL u) {
	//sum代表前缀和,sum[i]代表前i个人在u时间点内所贡献的理解力
	LL sum[N];
	for(int i=1; i<=t; i++) {
		sum[i]=sum[i-1]+max(0ll,u-arr[i].first)*arr[i].second;
	}
	for(int i=1;i<=t;i++){
		//如果去掉第i个人,总贡献度小于m,返回假 
		if(sum[t]-sum[i]+sum[i-1]<m)return false;
	}
	return true;
}
int main(void) {
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) {
		int a,b;
		scanf("%d%d",&a,&b);
		//如果一个人的理解速度是0,那么这个人对人类理解五维没有影响
		//且小度也不会为一个没有理解力的人耗费魔法
		if(b==0)continue;
		arr[++t]= {a,b};
	}
	//如果有理解力的人少于一个人,那么小度就可以抹杀这个人
	//那么就没有人类可以理解了
	if(t<=1) {
		printf("-1");
		return 0;
	}
	//假设只有一个人,且这个人开始理解的时间是2e9,理解速度是最少的1
	//而m为2e9,此时能达到最大的理解年份为4e9;
	LL l=1,r=4e9;
	while(l<r) {
		LL mid=l+r>>1;
		//如果能在mid时间理解,则验证是否有更短的时间也可以理解
		if(check(mid)) {
			r=mid;
		} else {
			l=mid+1;
		}
	}
	printf("%lld",r);
	return 0;
}

这段代码是一个解决特定问题的程序。它的目标是确定一个科学家群体能否在一定时间内理解五维概念,并找到理解五维所需的最短时间。代码中使用了二分查找算法来找到这个时间。

下面是对代码的逐行解析:

  1. #include<iostream>:包含C++标准输入输出库。
  2. using namespace std;:使用std命名空间,使得可以不必前缀std::来调用标准库的函数和对象。
  3. typedef long long LL;:将long long类型重定义为LL,便于阅读和理解。
  4. typedef pair<int,int> PII;:将pair<int, int>类型重定义为PII,这是一个用于存储两个整数对的类型。
  5. const int N=1e5+5;:定义一个常量N,值为100005。
  6. int n,m;:声明两个整数变量nm
  7. int t=0;:声明一个整数变量t并初始化为0,用于记录有理解力的科学家数量。
  8. PII arr[N];:声明一个PII类型的数组arr,大小为N,用于存储科学家的信息(包括他们的出现时间和理解力)。
  9. bool check(LL u) { ... }:定义一个函数check,输入参数是一个长整型数u,返回一个布尔值。这个函数用于检查在给定的时间u内,是否有足够的理解力来理解五维。
  10. main(void) { ... }:程序的主函数,从这里开始程序的执行。
  11. 在主函数中,首先通过输入获取两个整数nm,分别代表科学家的数量和需要的理解力。
  12. 接下来,通过循环读取每个科学家的出现时间和理解力,并将它们存储在数组arr中。
  13. 如果有理解力的科学家数量少于或等于1,则输出"-1"并结束程序。
  14. 否则,使用二分查找算法在1到4e9之间查找最短的理解时间。如果能在某个时间mid内理解五维,则进一步查找更短的时间;如果不能,则查找更长的时间。
  15. 最后,输出找到的最短理解时间。

这个程序的核心是二分查找算法和check函数的实现,它们共同决定了找到最短理解时间的效率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值