zoukankan      html  css  js  c++  java
  • 洛谷P1083 借教室---二分+差分

    题目链接:https://www.luogu.com.cn/problem/P1083

    题意:给定n天内,每天供应的教室数量ri和m个订单,表示第si到ti天用di个教室。按顺序执行订单,求第一个无法满足的订单编号

    看到样例之后大致知道了做法。对于每个订单,把数组r的区间[si,ti]减去di,最后第一个出现某个ri<0时的订单编号就是答案。求第一个无法满足的订单编号,显然可以二分。因为如果前面的满足,那么不满足的一定都在后面;如果当前的已经不满足,那么第一个不满足的一定为在这个编号以及它的前面。由于是先进行一些区间加减,最后再判断是否有某个ri<0,所以可以用差分

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=1e6+10;
    struct st{int d,s,t;}a[N];
    int c[N],r[N],pre[N],n,m,i,f,l,h;
    
    bool check(int mid){
    	memset(pre,0,sizeof(pre));
    	for (i=1;i<=n;i++) c[i]=r[i]-r[i-1];
    	for (i=1;i<=mid;i++){
    	  c[a[i].s]-=a[i].d; c[a[i].t+1]+=a[i].d;
    	}
    	for (i=1;i<=n;i++){
    	  pre[i]=pre[i-1]+c[i];
    	  if (pre[i]<0) { //*
    	  	f=-1; return false;
    	  }
    	}
    	return true;
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	for (i=1;i<=n;i++) scanf("%d",&r[i]);
    	for (i=1;i<=m;i++) scanf("%d%d%d",&a[i].d,&a[i].s,&a[i].t);
    	l=0; h=m; f=0;
    	while (h-l>1){
    	  int mid=(l+h)/2;
    	  if (check(mid)) l=mid; else h=mid;
    	}
        printf("%d
    ",f);
        if (f==-1) printf("%d",h);
    	return 0;
    }
    
  • 相关阅读:
    eclipse恢复界面默认设置
    文件夹的拷贝
    文件的输入输出
    十进制转二进制,八进制,十六进制(查表法)
    数组元素的查找(折半查找)
    C++几个小函数
    C++ 内部排序(一)
    C++实现链表
    C++输出IP地址段内的合法地址
    我看软件工程师的职业规划
  • 原文地址:https://www.cnblogs.com/edmunds/p/13692039.html
Copyright © 2011-2022 走看看