2 条题解
-
3
二分题 我们首先要找二分对象 很容易想到,应该按每一天的订单二分 问题来了,check函数怎么写 首先,我们需要一个前缀和的预处理,也就是把每一天需要的教室都算出来(我有注释) 然后我们只需要比较每一天所需要的和剩余的就行了 有两个需要注意的点 一个是要特判最后一天能否完成,如果能那就肯定够 第二个是每一次求前缀和的时候都需要清零 这里就不得不提STL的vector了,O(1)复杂度直接清零,轻轻松松不怕超时 那么到这里这道题就解决了 顺便一提 STL库的容器蒸的很好用!!!(龙叔音)
#include<bits/stdc++.h> using namespace std; int a[1000001],k[1000001]; vector<int>z(1000001); int n,m; struct apply{ int num1,begin1,end1; }h[1000001]; bool check(int y) { z.clear();//清空 z.resize(1000001);//重设 for(int i=1;i<=y;i++)//求前缀和 { z[h[i].begin1]+=h[i].num1;//这一天所需的 z[h[i].end1+1]-=h[i].num1;//当天结束了的要减去(+1是因为结束的那一天会多算一次(自己那笔模拟一下 } for(int i=1;i<=n;i++) { k[i]=k[i-1]+z[i];//当天所需的 if(k[i]>a[i]) return false;//需要的大于剩余的当然就不行了 } return true; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); a[i]=x; } for(int i=1;i<=m;i++) { scanf("%d%d%d",&h[i].num1,&h[i].begin1,&h[i].end1); } int l=1,r=m; if(check(m))//如果最后一天的订单可以,那就都可以 ,算一个小特判 { cout<<"0"; return 0; } while(l<r)//二分 { int mid=(l+r)/2; if(check(mid)) l=mid+1; else r=mid; } cout<<"-1"<<endl<<r; return 0; }
信息
- ID
- 205
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- 递交数
- 62
- 已通过
- 15
- 上传者