zoukankan      html  css  js  c++  java
  • P1083 [NOIP2012 提高组] 借教室

     

    不要把天数看成一个动态的时间,用数组存储某天原本有多少个教室,表示为第i天原有s[i]个教室.

    很容易看出来问题有单调性,所以二分订单数求解.

    对于每份订单,其将会使第a天到第b天的教室数量均减少c个.故构造一个差分数组sum,使得sum的前缀和表示对应某天教室数量的变化量.则当天剩余的教室数量为s[i]+(sum[i]的前缀和).

    一旦发现某天剩余教室数量小于0,说明不符合,可以很容易写出check函数.

    注意如果所有的check都返回了真,最后会有l==m+1,即r保持初始值未变且l增长到r.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    int n, m, s[1000010];
    int sum[1000010];
    struct S {
        int d, s, t;
    } a[1000010];
    
    bool check(int x) {
        memset(sum, 0, sizeof(int) * (n + 1));
        for (int i = 1; i <= x; i++) {
            sum[a[i].s] -= a[i].d;
            sum[a[i].t + 1] += a[i].d;
        }
        for (int i = 1; i <= n; i++) {
            sum[i] += sum[i - 1];
            if (sum[i] + s[i] < 0) return false;
        }
        return true;
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) scanf("%d", s + i);
        for (int i = 1; i <= m; i++) scanf("%d%d%d", &a[i].d, &a[i].s, &a[i].t);
    
        int l = 0, r = m + 1;
        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (check(mid))
                l = mid;
            else
                r = mid - 1;
        }
    
        if (l == m + 1)
            puts("0");
        else
            printf("-1
    %d
    ", l + 1);
    
        return 0;
    }
    P1083
  • 相关阅读:
    大数据并发控制思考
    同步和异步的区别
    java枚举使用详解
    利用反射实现动态方法调用
    利用反射查看类的声明信息
    用两个栈实现对列
    c标签 if else c标签 总结
    struts2标签获取parameter,request,session,application中的值
    mysql日期加减
    详细介绍Java中的堆、栈和常量池
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14258933.html
Copyright © 2011-2022 走看看