借教室 ——2012年NOIP全国联赛提高组

来源:互联网 发布:apm源码编译 编辑:程序博客网 时间:2024/05/16 18:08

在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要

向学校申请借教室。教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。

面对海量租借教室的信息,我们自然希望编程解决这个问题。

我们需要处理接下来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;}