zoukankan      html  css  js  c++  java
  • 【CF1443D】Extreme Subtraction 题解

    原题链接

    题意简介

    给出一个长度为 n 的数组,现在你能对它进行如下两种操作:

    1. 前 k 个数减 1
    2. 后 k 个数减 1

    问能否将每个元素减到 0 。

    思路分析

    乍一看是道很水的模拟题,可现实是我根本没想清楚。于是断断续续花了五六个小时才做出来。

    这道题的关键在于构造凹状/不递增数列

    从一个方向开始扫,每扫到一个比它的数,就意味着我们需要动用另一个方向的操作把它减小(至少减到恰好相等)。

    当另一个方向不能将它减到合适,即出现为了把它减到合适不得不把其它无辜的数减到小于 0 的情形,答案就是 No 。

    假如我们成功的做到了这一点,我们不难发现,此时我们已经构造出了扫的方向上的不递增数列。答案自然是 Yes 。

    所以我们只需要根据前缀和思想,维护从一个方向开始算起的最小值,然后从另一个方向扫数即可。需要注意的是减的操作对还没有扫的数生效且累加,所以还需要维护一个差值 d 。

    代码库

    #include <cstdio>
    #define REG register
    #define rep(i,a,b) for(REG int i=a;i<=b;i++)
    #define Rep(i,a,b) for(REG int i=a;i>=b;i--)
    template<typename T> inline T min(T a,T b){
        return a<b?a:b;
    }
    const int N=3e4+5; int n,A[N],minn[N],d,rmin;
    int main(){
        REG int t; scanf("%d",&t); minn[0]=1000005; 
        while(t--){
            scanf("%d",&n); d=0; 
            rep(i,1,n) scanf("%d",A+i),minn[i]=min(minn[i-1],A[i]);
            rmin=1000005; REG bool no=0;
            Rep(i,n,1){
                //当前值: A[i]-d
                //最小值(用于判断是否递减):rmin
                //描述减去了多少:d
                if(A[i]-d<=rmin) rmin=A[i]-d;
                else if(A[i]-d-rmin<=minn[i-1]-d) d+=A[i]-d-rmin; 
                else{ no=1; break; }
            }
            printf(!no?"Yes
    ":"No
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    承接小项目嵌入式linux相关开发、开源飞控相关开发、qt相关开发、无人机地面站相关开发
    转载 ardupilot 学习
    PX4 IO板启动流程
    PX4 FMU启动流程 1.nsh
    PX4 FMU启动流程 2. 一、 nsh_newconsole
    PX4 FMU启动流程 2. 二、 nsh_initscript
    Pixhawk源码快速阅读 02_进程间通信
    PX4 FMU [5] Loop
    Oracle 执行JOB程序自动存储数据
    C# 禁止非数字输入TextBoox
  • 原文地址:https://www.cnblogs.com/Qing-LKY/p/CF1443D-solution.html
Copyright © 2011-2022 走看看