CF round#481(div3) D
阿新 • • 發佈:2018-12-24
D. Almost Arithmetic Progression
description:
給出一個長度為n的數列,每個數最多可以操作一次,問最少操作多少次能把它變成等差數列。操作內容為,將一個數加一或者減一。
input:
第一行n
之後一行為n個數代表數列
output:
一個整數代表最少的操作次數
analysis:
解題很重要的一點是,題目的條件要用好,很多時候問題的條件就是突破口,如果題目要求要達成什麼樣的條件,不妨先假設已經達到了什麼樣的條件,然後再繼續往前看看有什麼發現。
比如這裡要充分用好等差數列這個的條件。因為是等差數列,所以只要前兩項就確定了唯一的數列。這樣就可以列舉數列前兩項再計算該數列的對應的操作次數,更新答案即可。
程式碼:
#include<iostream>#include<string>#include<cstring>#include<vector>#include<stack>#include<algorithm>#include<map>#include<set>#include<queue>#include<sstream>#include<cmath>#include<iterator>#include<bitset>#include<stdio.h> usingnamespace std;#define _for(i,a,b)for(int i=(a);i<(b);++i)#define _rep(i,a,b)for(int i=(a);i<=(b);++i)typedeflonglong LL;
LL readint(){ LL x; scanf("%lld",&x);return x;}constint INF =1<<30;constint maxn =100005;int n;int a[maxn];int a1[maxn];int cnt,ans;void solve(){int d=a1[1]-a1[0];for (int i=2;i<n;++i){int x=a1[i]-(a1[i-1]+d);if(abs(x)>1){return;}else{if(x!=0)cnt++;
a1[i]=a1[i-1]+d;}}
ans=min(ans,cnt);}int main(){//freopen("C:\\Users\\admin\\Desktop\\in.txt", "r", stdin);//freopen("C:\\Users\\admin\\Desktop\\out.txt", "w", stdout);while(~scanf("%d",&n)){for(int i=0;i<n;++i)scanf("%d",&a[i]);
ans=INF;if(n==1||n==2){
printf("0\n");}else{for(int dx=-1;dx<=1;++dx)for(int dy=-1;dy<=1;++dy){
memcpy(a1,a,sizeof(a));
a1[0]+=dx;a1[1]+=dy;
cnt=abs(dx)+abs(dy);
solve();}if(ans==INF)printf("-1\n");else printf("%d\n",ans);}}return0;}