题意:给定一个长度为n的数组,数组的每个元素可以进行+1或者-1操作。如果可以通过这两个操作,使数组变为等差数列,输出需要的最少操作。否则输出-1。
算法:枚举
题解:数组的第一个元素和第二个都有3种取值,枚举这9种排列。在每种情况下,算出公差d,则符合题意的数组就唯一确定了,把合法数组和原来的数组逐位比较,如果存在差的绝对值大于1,则说明这个合法数组是无法通过原数组得到的。否则当差的绝对值不为0的时候,cnt++。所有情况中最小的cnt即为答案。
代码:时间复杂度O(n)
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <iterator>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <deque>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define endl "\n"
#define IOS ios::sync_with_stdio(0);
#define debug(x) cout<<"**"<<x<<"**"<<endl;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int mod = 998244353;
const int N = 3e5 + 100;
int n, cnt, ans = inf, f;
int a[N], b[N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
#endif
IOS;
cin>>n;
for(int i = 1; i <= n; i++) cin>>a[i];
for(int x = a[1]-1; x <= a[1]+1; x++)
{
for(int y = a[2]-1; y <= a[2]+1; y++)
{
int d = y-x;
f = 0; cnt = 0;
for(int i = 1; i <= n; i++)
{
if(abs(x+d*(i-1) - a[i]) <= 1)
if(abs(x+d*(i-1) - a[i]) != 0)
cnt++;
else
{
f = 1;
break;
}
}
if(f == 1) continue;
ans = min(ans, cnt);
}
}
if(ans == inf) cout<<-1;
else cout<<ans;
return 0;
}