zoukankan      html  css  js  c++  java
  • codevs1217 借教室 题解

    codevs1217 借教室 题解

    题意

    /中文题惯例不翻译

    笺释

    这道题确实不好过,内存方面和时间方面要求都相当严格呢。
    思路的话无非二分人数,最小第一个人就要取消掉,最大的话m个人都能满足,并且第i个人能满足的话,i个人之前的一定也满足(否则在之前就取消掉了)。
    但是如何确定第i个人能否满足呢,这道题用到的是差分数组的方法,

    int check(int x)
    {
        int ans=0;
        //pre[i]:差分数组 里面存的是能让ans代表第i天所需教室的数字
        for(int i=1;i<=n;i++)
        {
            pre[i]=0;
        }
        for(int i=1;i<=x;i++)
        {
            pre[s[i]]+=d[i];
            pre[t[i]+1]-=d[i];
        }
        for(int i=1;i<=n;i++)
        {
            ans+=pre[i];
            if(ans>r[i])
            {
                return 0;
            }
        }
        return 1;
    }
    

    具体想表达的感觉就已经完全被表达出来了,不知道能不能说明白呢,时常为此感到困惑。
    互相理解果然是需要双方的共同努力才行的呢,不过对于我来说,也确实存在着诸多表达方面的问题,不过自己能否理解自己呢,我想,总是要让自己多多少少或是完完全全地理解自己才行的。

    完整代码

    #include<bits/stdc++.h>
    #define MAXN 1000005
    using namespace std;
    int n,m;
    int r[MAXN];
    int d[MAXN],s[MAXN],t[MAXN];
    int pre[MAXN];
    int check(int x)
    {
        int ans=0;
        //pre[i]:差分前缀数组 里面存的是能让ans代表第i天所需教室的数字
        for(int i=1;i<=n;i++)
        {
            pre[i]=0;
        }
        for(int i=1;i<=x;i++)
        {
            pre[s[i]]+=d[i];
            pre[t[i]+1]-=d[i];
        }
        for(int i=1;i<=n;i++)
        {
            ans+=pre[i];
          //  printf("%d %d
    ",ans,i);
            if(ans>r[i])
            {
                return 0;
            }
        }
        return 1;
    }
    int solve()
    {
        int l=1;
        int r=m;
        while(l<=r)
        {
            //printf("%d %d
    ",l,r);
            int mid=(l+r)>>1;
            if(check(mid))
            {
                l=mid+1;
            }
            else
            {
                r=mid-1;
            }
        }
        if(l<=m)
        {
            printf("-1
    %d
    ",l);
        }
        else
        {
            printf("0
    ");
        }
            return 0;
    }
    int main()
    {
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&r[i]);
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d %d",&d[i],&s[i],&t[i]);
        }
        solve();
    }
    
  • 相关阅读:
    [读书笔记]-技术学习-微服务架构与实践
    [文章转载]-Java后端,应该日常翻看的中文技术网站 -江南白衣
    [文章转载]-我的Java后端书架-江南白衣
    正则表达式有多强大一看便知!
    微信小程序支付功能完整流程
    判断字符串是否合法(1)
    ES6新增常用方法
    JS求一个字符串在另一个字符串中出现的次数
    根据对象的某个属性排序
    数组去除重复值的四种超简便方法
  • 原文地址:https://www.cnblogs.com/SoniciSika/p/9034208.html
Copyright © 2011-2022 走看看