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;
}

浙公网安备 33010602011771号