noip2018提高组初赛解析_noip小学组

noip2018提高组初赛解析_noip小学组【问题简述】给定一个数n表示教室数接下来n个数r[i],表示每天可以借用的教室数量。有m份订单,每份订单有三个数d[i],s[i],t[i]。表示从S[i]天到t[i]天,借用d[i]个教室。现在询问能否满足所有订单。如果能,则输出0不能,则输出-1,换行输出最早不能满足的订单。【输入样例】432543213324424…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

【问题简述】

给定一个数n表示教室数
接下来n个数r[i],表示每天可以借用的教室数量。
有m份订单,每份订单有三个数d[i],s[i],t[i]。表示从S[i]天到t[i]天,借用d[i]个教室。
现在询问能否满足所有订单。
如果能,则输出0
不能,则输出-1,换行输出最早不能满足的订单。

【输入样例】

4 3
2 5 4 3
2 1 3
3 2 4
4 2 4

【输出样例】

-1
2


【分析】

从数据范围看(n,m≤1,000,000),算法的时间复杂度应在O(n)到O(nlogn)之间。可以用线段树维护,也可以用差分树状数组来维护。此处我们来使用一种神奇的算法。
大体思路是用二分答案二分时间,再用差分数组检验答案是否冲突。

二分答案不解释。。。

差分数组这块,懂得可以直接看代码。注意:差分本质是一种离线算法对于一个数列,我们用diff数组,表示后一个与前一个数的差值。例如:在[a,b]的区间中加上Δ(delta),我们可以使diff[a]+=Δ,并使diff[b+1]-=Δ。

完成差分数组的计算后,从左向右再计算一次即可得到每天的总共订单数的确切值。判断是否有一天的预定教室数>固有教室数

附上代码一份:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1000010;
struct node
{
    int d,s,t;
}q[maxn];
int n,m;
int r[maxn];
int read()
{
    int x=0;
    char tmp;
    tmp=getchar();
    while(tmp<'0'||tmp>'9') tmp=getchar();
    while(tmp>='0'&&tmp<='9')
    {
        x=(x<<1)+(x<<3)+tmp-'0';
        tmp=getchar();
    }
    return x;
}
int diff[maxn];
bool check(int x)
{
    memset(diff,0,sizeof(diff));
    for(int i=1;i<=x;i++)
    {
        diff[q[i].s]+=q[i].d;
        diff[q[i].t+1]-=q[i].d;
    }
    int tmp=0;
    for(int i=1;i<=n;i++)
    {
        tmp+=diff[i];
        if(tmp>r[i]) return 0;
    }
    return 1;
}
int main()
{
    freopen("classroom.in","r",stdin);
    freopen("classroom.out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;i++)
        r[i]=read();
    for(int i=1;i<=m;i++)
        q[i].d=read(),q[i].s=read(),q[i].t=read();
    int l=1,r=m,ans=0;
    while(l<=r)
    {
        int mid=l+r>>1;
        if(check(mid)) l=mid+1;
        else ans=mid,r=mid-1;
    }
    if(!ans) printf("0\n");
    else printf("-1\n%d",ans);
    return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/172062.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 怎么关闭磁盘共享(电脑如何关闭默认共享)

         Windows2000/XP/2003版本的操作系统提供了默认共享功能,这些默认的共享都有“$”标志,意为隐含的,包括所有的逻辑盘(C$,D$,E$……)和系统目录Winnt或Windows(admin$)。   带来的问题:   微软的初衷是便于网管进行远程管理,这虽然方便了局域网用户,但对我们个人用户来说这样的设置是不安全的。如果电脑联网,网络上

    2022年4月11日
    1.1K
  • Zynq-Linux移植学习笔记之一-入门[通俗易懂]

    Zynq-Linux移植学习笔记之一-入门[通俗易懂]1、相关网站zynqlinux软件网站:www.wiki.xilinx.comzynqu-bootgithub地址:https://github.com/xilinx 2、启动过程3、u-boot配置3.1下载u-bootUBOOT有多个版本,可以去网站上下载相应的版本。14.5及早期的版本对Micron的QSPIFlash芯片支持不完整。建议下载后期

    2022年9月2日
    3
  • webstorm正则替换(正则替换字符串)

    Command+R 进入替换页面,选择Regex,进行正则替换。参考页面https://www.jetbrains.com/help/webstorm/2016.1/regular-expression-syntax-reference.html

    2022年4月10日
    159
  • springboot设置时区不起作用_docker设置时区

    springboot设置时区不起作用_docker设置时区第一步:确认docker时区进入容器中dockerexec-it容器namebash查看容器时区:date第二步确认数据库时区SELECTTIMEDIFF(NOW(),UTC_TIMESTAMP);如果显示的是08:00:00则是cst时区。如果不是cst时区,则执行Sql:setglobaltime_zone=’+8:00′;##修改mysql全局时区为北京时间,即我们所在的东8区settime_zone=’+8:00′;.

    2022年9月25日
    0
  • Git下载安装及设置详细教程

    Git下载安装及设置详细教程文章作者:Wendell原文地址:https://www.jianshu.com/p/a152f82c5e4a转载请注明出处!一、安装前准备  1.廖雪峰老师Git教程:推荐Git入门教程。  2.按照自己的系统版本下载Git软件,我的操作系统:Windows764位,安装版本为Git-2.18.0-64-bit.exe(截至201…

    2022年4月28日
    50
  • matlab画折线图,标记指定点「建议收藏」

    matlab画折线图,标记指定点「建议收藏」首先,找到你需要标注的点。比如说你有x、y两个列向量构成一条曲线。现在要找最大值点那么用p=find(y=max(y)),那么坐标(x(p),y(p))就是你要找的点咯。2第二步如何标记。我介绍两总方法来标记这个点,但是总体上可以归结为一种方法。(1)利用text(x(p),y(p),’o’,’color’,’g’));这里o表示标注的形状,也可以用*、^等比较好看的符号哟。’g’表示的是颜色。(…

    2022年5月20日
    52

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号