借教室 洛谷(超详细教程)

借教室 洛谷(超详细教程)

思路:

请慢下来一点一点看你就会懂
1、我们要找到满足借教室的条件,如果可以借最后是零,如果不满足我们输出-1和这个人的序号。
2、我们会用到二分和前缀和以及差分
3、我们直接暴力肯定不能过。所以我们先在多少个人的区间上二分去找那个人(因为人是按照顺序去借教室的我们可以理解为有序)。假设有n个人那么这个区间就是1到n,我们在这上面二分。
4、接下来当我们二分一个人的时候我们把这个人前面所有人的教室加起来看看大不大于提供的教室数量。如果大了,我们就再二分小一点,反之就大一点。
前提是你会二分前缀和以及差分(不会没事,看我其他作品有的哦)

我把代码分了几个部分其实很好理解的,希望可以帮到你

#include<bits/stdc++.h>
using namespace std;
const long long N = 1000000;
int n,m;
long long a[N],b[N],c[N],d[N],e[N]={0};
bool check(int mid)
{
	
	memset(e,0,sizeof(e));//这个函数是初始化数组的
	//这一部分是加起来二分前面所有人的借的教室数量
	for(int i=1;i<=mid;i++)
	{
		int l=c[i],r=d[i],x=b[i];
		e[l]+=x;
		e[r+1]-=x;
	}
    //
    
    //这就是比较这些人接的教室数量大不大于教室拥有量
	for(int i=1;i<=n;i++)
	{
		e[i]+=e[i-1];
		if(e[i]>a[i])
		return true;
	}
	//
	return false;
}
int main()
{	
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
	}
	int l=1,r=m,ans=0;
	for(int i=1;i<=m;i++)
	{
		scanf("%lld%lld%lld",&b[i],&c[i],&d[i]);
	}
    //这上面的是录入数据(用long long啊)

    //这就是二分模板了
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(check(mid))
		{
			ans=mid;
			r=mid-1;
		}
		else
		l=mid+1;
	}
	//

	if(ans==0)
	{
		cout<<0;
	}
	else
	{
		cout<<-1<<endl<<ans;
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值