zoukankan      html  css  js  c++  java
  • D. Cleaning 前缀后缀

    D. Cleaning 前缀后缀

    题目大意:

    给你一个大小为n的数组,你可以进行一个操作:

    • 选择两个相邻的数,如果两个数都大于0,则可以对两个数进行-1的操作

    你可以进行一次或者0次特殊操作:

    • 选择两个相邻的数,交换他们

    题解:

    这个题目其实很简单,以前经常写这种类型的题目,但是最近可能很久没有刷题了,居然没有写出来。

    这个特殊操作可以进行一次或者0次,那么就枚举这个特殊操作在哪里即可,这个时候我们就要O(1) 判断这个操作是否可行,首先要明白,如果没有这种特殊操作,那么我只需要从前往后判断或者从后往前是否可行即可,但是有这种操作了,枚举 ii+1 ,那么我判断 i-1 往前和 i+2 往后都是可行的即可。然后再 O(1) 判断这个交换操作的可行性。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5+10;
    int pre[maxn],suffer[maxn],a[maxn];
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int n;
            scanf("%d",&n);
            for(int i=0;i<=n+10;i++) pre[i] = suffer[i] = 0;
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                if(a[i]>=pre[i-1]) pre[i] = a[i] - pre[i-1];
                else pre[i] = inf;
            }
            for(int i=n;i>=1;i--){
                if(a[i]>=suffer[i+1]) suffer[i] = a[i] - suffer[i+1];
                else suffer[i] = inf;
            }
            bool flag = false;
            if(pre[n]==0||suffer[1]==0) flag = true;
            for(int i=1;i<n;i++){
                if(pre[i]!=inf&&pre[i]==suffer[i+1]) flag = true;
                if(a[i+1]>=pre[i-1]&&a[i]>=suffer[i+2]&&a[i+1]-pre[i-1]==a[i]-suffer[i+2]) flag = true;
            }
            if(flag) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    【NOIP2016提高A组8.12】奇袭
    【NOIP2016提高A组8.12】礼物
    tarjan算法
    【NOIP2016提高A组8.12】总结
    【NOIP2016提高A组8.11】自然数
    【NOIP2016提高A组8.12】通讯
    【NOIP2016提高A组8.11】种树
    【NOIP2016提高A组8.11】钱仓
    【NOIP2016提高组A组7.16】大鱼海棠
    【NOIP2012模拟8.20】Memory
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/14315046.html
Copyright © 2011-2022 走看看