#include<stdio.h>
#include<math.h>
#include<string.h>
#define LL long long
LL a[100009], b[100009], n, k, judge, p;
//a为改变后的等差数列,b为输入的数组
int main()
{
while(~scanf("%lld", &n)) //n为输入的数组元素数量
{
for(LL i = 0; i < n; i++) //输入数据
{
scanf("%lld", &b[i]);
}
if(n==1||n==2)
{
printf("0\n");
continue;
}
LL minn=1000000000000;
k = 0; //k为改变的次数
for(LL i = -1; i < 2; i++)
{
for(LL j = -1; j < 2; j++) //这两个循环改变b1,b2
{
k=0;
judge=1; //judge为是否能够成为等差
a[0] = b[0] + i; //固定前两个元素的值
a[1] = b[1] + j;
if(i!=0)k++; //若+1或-1则算改变,k++
if(j!=0)k++;
t = a[1] - a[0]; //t为公差
//printf("t::%lld\n",t);
for(LL m = 2; m < n; m++) //自第三个元素开始判定
{
p = 0; //p=0代表改元素改变后无法构成等差
for(LL z = -1; z < 2; z++)
{
//printf("%lld:::\n",a[m-1]);
if(a[m-1] + t == b[m] + z) //判定是否构成等差
{
//printf("%lld %lld \n",a[m-1]+t,b[m]+z);
a[m] = b[m] + z;
if(z!=0)
k +=1;
p = 1; //p=1代表改元素改变后能构成等差
break;
}
}
if(p == 0) //只要有一次p==0则无法构成等差
{
judge = 0; //此时更新judge为0,代表无法构成
break; //无法构成,跳出循环
}
}
if(judge==1) //在全部元素判定完毕后,若judge没有被更新为0,则能构成等差
{
if(minn>k) //将此种情况下的k与minn比较
{
minn=k; //存储最小值
}
}
}
}
if(minn == 1000000000000) //minn未改变,即无法构成等差
{
puts("-1"); //输出-1
}
else
{
printf("%lld\n", minn); //输出k的最小值
}
}
return 0;
}
题意
给你一个数组,你可以将其中的值+1,-1或不变,若能通过这种改变使改数组成为等差数组,则输出改变值的次数,若不能,则输出-1。
思路
本题要求将数组变为等差数组,因此可以通过固定前两个元素的值,计算出公差后,再判定之后的元素是否能变成等差数组。