zoukankan      html  css  js  c++  java
  • 题解 P4552 【[Poetize6] IncDec Sequence】

    这是一道水题

    题目:
    给定一个长度为 n 的数列 a1,a2,…,an,每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一。求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。
    输入格式
    第一行输入正整数n。
    接下来n行,每行输入一个整数,第i+1行的整数代表ai。
    输出格式
    第一行输出最少操作次数。
    第二行输出最终能得到多少种结果。
    数据范围
    0<n≤1e5,
    0≤ai<2147483648
    输入样例:
    4
    1
    1
    2
    2
    输出样例:
    1
    2


    这道题,我觉得代码难度不大,但是思维难度还是有的qwq。
    刚拿到这道题,我第一眼看过去还以为是积木大赛(是我瞎了,对不起)
    但是,看到这道题,我们会想到使用差分,所以,我就试着用差分写一下。然后,好像就过了(震惊.jpg)
    下面就来说一下这道题。
    首先,我们得到这个数列之后先将这个数列进行差分,得到差分数组b[1]~b[n+1]
    我们再来考虑一下本题目的要求,使我们得到完全一致的数列,那么转换到差分数组来说,就是2~n全部为0。
    所以,我们的每一次修改对于差分数组来说,就只会修改两个数

    操作1:修改b[i],b[j](2≤i,j≤n)这步操作对于一正一负的操作十分有效。
    操作2: 修改b[1],b[i]这步操作对于正数变为0进行有效操作。
    操作3: 修改b[i],b[n+1]这步操作对于负数变为0进行有效操作。
    操作4:修改b[1],b[n+1],此操作无效,并没有对数列产生有效影响。

    所以,当我们梳理完可以对于差分数组的所有有效操作后,我们就可以很简单的得出答案。
    我们要统计b[2]~b[n]中间正数的和sumz,负数的和sumf
    如果对于sumf和sumz我们要尽可能多的进行操作1,对于剩余的进行操作2、3,即可。又因为每一次操作2、3,对于b[1]的影响不同,所以方案数不同。
    操作次数:max(sumf,sumz)
    方案数: |sumf-sumz|+1
    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=1e5+7;
    int b[N],a[N],n;
    long long sumz,sumf;
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            b[i]=a[i]-a[i-1];
        }
        // b[n+1]=0;
        for(int i=2;i<=n;i++){
            if(b[i]>0)sumz+=b[i];
            else sumf+=b[i];
        }
        sumf*=-1;
        // printf("%lld %lld
    ",sumz,sumf);
        printf("%lld
    ",max(sumz,sumf));
        printf("%lld
    ",abs(sumz-sumf)+1);
    }
    

    这道题是一道差分好题,比较考验思维。

  • 相关阅读:
    Binary Tree Paths
    Implement Stack using Queues
    Path Sum II
    Path Sum
    Plus One
    Add Digits
    Missing Number
    H-Index II
    H-Index
    Ugly Number II
  • 原文地址:https://www.cnblogs.com/xishirujin/p/11413612.html
Copyright © 2011-2022 走看看