题目大意:
有一些教室
我们需要处理接下来n天的借教室信息 其中第i天学校有ri个教室可供租借
共有m份订单 每份订单用三个正整数描述 分别为dj sj tj 表示从第sj天到第tj天租借教室 每天需要租借dj个教室
对于每份订单,我们只需要每天提供dj个教室 而它们具体是哪些教室 每天是否是相同的教室则不用考虑
借教室的原则是先到先得 也就是说我们要按照订单的先后顺序依次为每份订单分配教室
如果在分配的过程中遇到一份订单无法完全满足 则需要停止教室的分配 通知当前申请人修改订单
这里的无法满足指从第sj天到第tj天中有至少一天剩余的教室数量不足dj个
现在需要知道 是否会有订单无法完全满足 如果有 需要通知哪一个申请人修改订单
思路:
因为直接做不好做
可以二分答案
判断到mid是否是符合题意的 如果不满足就向左
然后check的时候差分来判断每天超没超
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstdlib> 6 #include<cstring> 7 #include<queue> 8 #include<map> 9 #include<vector> 10 #define ll long long 11 #define inf 2147483611 12 #define MAXN 1000100 13 #define MOD 1000000 14 using namespace std; 15 inline int read() 16 { 17 int x=0,f=1;char ch=getchar(); 18 while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} 19 while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();} 20 return x*f; 21 } 22 int n,m,a[MAXN],d[MAXN],s[MAXN],t[MAXN],g[MAXN]; 23 bool check(int x) 24 { 25 memset(g,0,sizeof(g)); 26 for(int i=1;i<=x;i++) 27 g[s[i]]+=d[i],g[t[i]+1]-=d[i]; 28 for(int i=1;i<=n;i++) 29 { 30 g[i]+=g[i-1]; 31 if(g[i]>a[i]) return 0; 32 } 33 return 1; 34 } 35 int main() 36 { 37 n=read(),m=read(); 38 for(int i=1;i<=n;i++) a[i]=read(); 39 for(int i=1;i<=m;i++) d[i]=read(),s[i]=read(),t[i]=read(); 40 int l=1,r=n,mid; 41 if(check(r)) {puts("0");return 0;} 42 while(l<r-1) 43 { 44 mid=(l+r)>>1; 45 if(check(mid)) l=mid; 46 else r=mid; 47 } 48 if(l==1&&!check(l)) l=0; 49 printf("-1\n%d",l+1); 50 }
时间: 2024-11-13 09:13:48