题意:
n个数组成的序列a,每个数可以进行减1、不变、加1这3种操作的1种,是否可以把该序列变为等差数列。若可以,输出最小改变次数,若不可以,输出-1。1 <= n <= 1e6。
题解:
1.枚举首尾两个数字,共9种情况,计算出公差dis。然后判断第i个数字会不会变成a[1] + dis * (i - 1)。
#include<bits/stdc++.h>
#define N 100005
#define mod 998244353
using namespace std ;
int n ;
int a[N] ;
int change[3] = {-1 , 0 , 1} ;
int main()
{
int i , j , k ;
int dis ;
int temp1 , temp2 ;
int ans = N , num ;
bool flag ;
scanf("%d" , &n) ;
for(i = 1 ; i <= n ; i ++)
scanf("%d" , &a[i]) ;
if(n == 1 || n == 2)
{
printf("0") ;
return 0 ;
}
for(i = 0 ; i < 3 ; i ++)
for(j = 0 ; j < 3 ; j ++)
{
temp1 = a[1] ;
temp2 = a[n] ;
temp1 += change[i] ;
temp2 += change[j] ;
if((temp2 - temp1) % (n - 1) == 0)
{
dis = (temp2 - temp1) / (n - 1) ;
num = 0 ;
flag = 0 ;
for(k = 2 ; k <= n - 1 ; k ++)
if(abs(temp1 + dis * (k - 1) - a[k]) <= 1)
num += abs(temp1 + dis * (k - 1) - a[k]) ;
else
{
flag = 1 ;
break ;
}
if(!flag)
ans = min(ans , num + abs(change[i]) + abs(change[j])) ;
}
}
if(ans == N)
ans = -1 ;
printf("%d" , ans) ;
}