zoukankan      html  css  js  c++  java
  • CF1453B

    题意:给你一个长度为n的数列,首先你可以改变任意一个数(这次不算操作),之后你可以选择如下操作:

    ①让任意后缀都加上1

    ②让任意后缀都减去1

    问你至少要进行几次操作,可以让数列所有数相等

    思路:首先假如不改变任何数的话,我们的操作数应该是abs(a[i]-a[i-1])的前缀和。如果要改变某个数的话,只是abs(a[i]-a[i-1])和abs(a[i+1]-a[i])会发生改变,a[i-1]到a[i+1]这段会直接变成abs(a[i-1]-a[i+1]),O(1)时间就能求出答案,所以我们只要枚举每个数,假设他要改变,然后取最小值就好了。同时要注意,左右两个端点只有一个相邻的数,可以直接改变成相等的两个数,操作数直接变成0

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 2e5+10;
    ll a[N];
    ll s[N];
    int n;
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
          int n;
          scanf("%d",&n);
          memset(s,0,sizeof(s));
          for(int i=1;i<=n;i++)
          {
            scanf("%lld",&a[i]);
            if(i>1)
                s[i]=abs(a[i]-a[i-1]);
          }
           if(n==2)//两个数直接出0
            cout<<0<<endl;
          else
          {
              ll sum=0;
            for(int i=2;i<=n;i++)
            {
              sum+=s[i];
            }
            ll ans=1e18;//这题要开ll
            for(int i=1;i<=n;i++)
            {
                if(i==1||i==n)//注意边界
                ans=min(ans,sum-s[i]-s[i+1]);
                else
                ans=min(ans,sum-s[i]-s[i+1]+abs(a[i+1]-a[i-1]));
            }
            cout<<ans<<endl;
          }
        }
    return 0;
    }
    
    
    戒骄戒躁,百炼成钢!
  • 相关阅读:
    MyBatis+Oracle+Sequence
    原来这就是JVM垃圾
    JVM内存布局
    CacheAsidePattern结论
    The LMAX Architecture
    网络编程
    随机存取文件流
    数据流
    打印流
    标准输入流、标准输出流
  • 原文地址:https://www.cnblogs.com/Pecoz/p/14116356.html
Copyright © 2011-2022 走看看