Codeforces 2112B Shrinking Array 题解 [ 橙 ] [ 贪心 ] [ 折线图 ]

Shrinking Array:很妙的一道题。

发现修改操作只能修改成两数的中间值,考虑把它画在一个折线图上考虑。

在折线图上,显然如果我们找到了一个单峰 / 单谷,那么一定可以在一步内把数组变美丽,因为将单峰 / 单谷的一侧直接变得与另一侧相等即可。

如果一张折线图上没有单峰 / 单谷,就证明这个函数是单调的,此时如果原来就不是美丽数组,那么此时也不可能变成美丽数组,因为折线图上只能将两个点合并为一个中间点。

就此判断即可,时间复杂度 \(O(n)\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
#define lc(x) (tr[x].ls)
#define rc(x) (tr[x].rs)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
const int N=1005,inf=0x3f3f3f3f;
int n,a[N],ans;
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    ans=inf;
    for(int i=1;i<n;i++)
    {
        if(a[i]==a[i+1]||abs(a[i+1]-a[i])==1)ans=min(ans,0);
        if(i>1&&a[i]>a[i-1]&&a[i]>a[i+1])ans=min(ans,1);
        if(i>1&&a[i]<a[i-1]&&a[i]<a[i+1])ans=min(ans,1);
    }
    if(ans>=inf)cout<<-1<<'\n';
    else cout<<ans<<'\n';
}
int main()
{
    //freopen("sample.in","r",stdin);
    //freopen("sample.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)solve();
    return 0;
}
posted @ 2025-07-02 21:36  KS_Fszha  阅读(80)  评论(0)    收藏  举报