ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

借教室NOIP2012

2022-08-01 21:33:31  阅读:138  来源: 互联网

标签:return NOIP2012 int isok 教室 long diff


题目:

 

 

 这道题目就是差分加二分答案。

先看为什么能差分,因为题目中的从s[j]借到t[j]就相当于对一个区间进行操作;再看为什么能二分,废话有单调性啊因为可以借n个教室那也可以借n个以下的教室,相反如果不能借n个教室也就不能借n个以上的教室。

再来讲程序,先将n,m.....(一大堆读进来)

再来说关键函数isok(x)返回一表示可以借x个教室,0相反。

isok函数

他先把diff(差分数组)清零,然后更新这个差分数组。

再用更新的diff来更新need数组(这两步操作是求总共有几个借教室的如果大于need[i],在i时空闲的教室数return 0,不行)

最后return 1;

不行的已在上述循环中return 0了

在主程序中,优化if(isok(m)) cout<<"0";return 0;       懂得都懂。

最后套二分模板即可(main)

程序:

#include<bits/stdc++.h>
using namespace std;
const int N=1000011;
int n,m;
long long diff[N];
long long need[N]={0},l[N]={0},r[N]={0},d[N]={0},rest[N];
bool isok(int x)
{
    memset(diff,0,sizeof diff);
    for(int i=1;i<=x;i++)
    {
        diff[l[i]]+=d[i];
        diff[r[i]+1]-=d[i];
    }
    for(int i=1;i<=n;i++)
    {
        need[i]=need[i-1]+diff[i];
        if(need[i]>rest[i]) return 0;
    }
    return 1;
}
int main()
{
#ifdef LOCAL
    freopen( "1.in", "r", stdin );
    freopen( "1.out", "w", stdout );
#endif
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&rest[i]);
    for(int i=1;i<=m;i++) scanf("%d%d%d",&d[i],&l[i],&r[i]);
    if(isok(m))
    {
        cout<<"0";
        return 0;
    }
    int begin=1,end=m;
    while(begin<end)
    {
        int mid=(begin+end)/2;
        if(isok(mid)==1) begin=mid+1;
        else end=mid;
    }
    cout<<"-1"<<endl<<begin;
    return 0;
}

 

标签:return,NOIP2012,int,isok,教室,long,diff
来源: https://www.cnblogs.com/wjk53233/p/16541829.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有