在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要
向学校申请借教室。教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。
面对海量租借教室的信息,我们自然希望编程解决这个问题。
我们需要处理接下来n天的借教室信息,其中第i天学校有ri个教室可供租借。共有m份
订单,每份订单用三个正整数描述,分别为dj, sj, tj,表示某租借者需要从第sj天到第tj天租
借教室(包括第sj天和第tj天),每天需要租借dj个教室。
我们假定,租借者对教室的大小、地点没有要求。即对于每份订单,我们只需要每天提
供dj个教室,而它们具体是哪些教室,每天是否是相同的教室则不用考虑。
借教室的原则是先到先得,也就是说我们要按照订单的先后顺序依次为每份订单分配教
室。如果在分配的过程中遇到一份订单无法完全满足,则需要停止教室的分配,通知当前申
请人修改订单。这里的无法满足指从第sj天到第tj天中有至少一天剩余的教室数量不足dj个。
现在我们需要知道,是否会有订单无法完全满足。如果有,需要通知哪一个申请人修改
订单。
第一行包含两个正整数n, m,表示天数和订单的数量。
提高组 day2
第二行包含n个正整数,其中第i个数为ri,表示第i天可用于租借的教室数量。
接下来有m行,每行包含三个正整数dj, sj, tj,表示租借的数量,租借开始、结束分别在
第几天。
每行相邻的两个数之间均用一个空格隔开。天数与订单均用从1开始的整数编号。
数据范围 1~2^6算法 二分+括号法
#include<bits/stdc++.h>
typedef long long ll;const ll MAXN=1000005;
ll t ,n,m,ans;
ll cy[MAXN],room[MAXN];
using namespace std;
struct node_1 {
ll d,s,t;
} day[MAXN];
ll read() {
int f=1;ll r=0;
char c=getchar();
while(c<'0'||c>'9') {
if(c=='-')f=-1;
c=getchar();}
while(c>='0'&&c<='9') {
r=r*10+c-'0';
c=getchar();
}
return f*r;
}
bool pd(ll y) {
ll js=0;
for(ll j=1; j<=n; j++)cy[j]=0;
for(ll i=1; i<=y; i++) {
cy[day[i].s]+=day[i].d;
cy[day[i].t+1]-=day[i].d;
}
for(ll h=1; h<=n; h++)//注意每份订单都会影响每天的租借数量;
{
js+=cy[h];
if(js > room[h])
return false;
}
return true;
}
int main () {
n=read();m=read();
for(ll i=1; i<=n; i++) {
room[i]=read();
}
for(ll j=1; j<=m; j++) {
day[j].d=read();
day[j].s=read();
day[j].t=read();
}
ll r=m,l=0,mid;
if(pd(m)){
cout<<"0";return 0;}//
while(r-l>0)
{ mid=(l+r+1)/2;
//cout<<"mid"<<mid<<endl;
if(pd(mid))l=mid;
else r=mid-1;
if(r==l){
if(pd(r))ans=r;
else ans=r-1;
}
//cout<<"left"<<l<<" "<<"right"<<r<<endl;
}
cout<<"-1"<<endl<<ans+1;
return 0;
}