题意:
题目给定一个序列,你可以对其中的数进行1次操作,这个操作可以为对这个数+1, -1, 不变,然后使其变成一个序列,使相邻的两个相减 的差是一样的,问最少的操作次数。
思路:
考虑第一个元素即可对第一个元素进行处理
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int n;
int a[N], cha[N], temp[N];
set<int> se;
int jisuanit()
{
int countt = 0;
for (int i = 1; i <= n; ++i)
{
if (temp[i] != a[i])
++countt;
}
return countt;
}
bool checkbubian(int x)
{
temp[1] = a[1];
for (int i = 1; i <= n; ++i)
{
temp[i] = temp[1] + x * (i - 1);
}
for (int i = 1; i <= n; ++i)
{
if (abs(temp[i] - a[i]) > 1)
return false;
}
return true;
}
bool checkjia1(int x)
{
temp[1] = a[1] + 1;
for (int i = 1; i <= n; ++i)
{
temp[i] = temp[1] + x * (i - 1);
}
for (int i = 1; i <= n; ++i)
{
if (abs(temp[i] - a[i]) > 1)
return false;
}
return true;
}
bool checkjian1(int x)
{
// if (x == 3)
// cout << "whfjdkjfko" << endl;
temp[1] = a[1] - 1;
for (int i = 1; i <= n; ++i)
{
temp[i] = temp[1] + x * (i - 1);
}
for (int i = 1; i <= n; ++i)
{
if (abs(temp[i] - a[i]) > 1)
return false;
}
return true;
}
signed main()
{
IOS; cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
if (i == 1)
continue;
se.insert(a[i] - a[i - 1]);
}
int start = 1e9, end = -1e9;
for (auto it : se)
{
if (it < start)
start = it;
if (it > end)
end = it;
}
// if (end - start > 100)
// {
// //cout << "end: " << end << " " << "start: " << start << endl;
// cout << "-1" << endl;
// return 0;
// }
if ((n == 1) || (n == 2))
{
cout << "0" << endl;
return 0;
}
if (end - start > 4)
{
//cout << "end: " << end << " " << "start: " << start << endl;
cout << "-1" << endl;
return 0;
}
for (int i = start - 100; i <= end + 100; ++i)
{
se.insert(i);
}
int ans = 1e9;
for (auto it : se)
{
if (checkbubian(it))
{
ans = min(ans, jisuanit());
}
if (checkjia1(it))
{
ans = min(ans, jisuanit());
}
if (checkjian1(it))
{
//cout << "hahaha" << endl;
ans = min(ans, jisuanit());
}
}
if (ans == 1e9)
cout << "-1" << endl;
else
cout << ans << endl;
return 0;
}