• CF Round 481 (Div. 3)--D. Almost Arithmetic Progression(思维)


    Polycarp likes arithmetic progressions. A sequence [a1,a2,…,an] is called an arithmetic progression if for each i (1≤i

    It follows from the definition that any sequence of length one or two is an arithmetic progression.

    Polycarp found some sequence of positive integers [b1,b2,…,bn]. He agrees to change each element by at most one. In the other words, for each element there are exactly three options: an element can be decreased by 1, an element can be increased by 1, an element can be left unchanged.

    Determine a minimum possible number of elements in b which can be changed (by exactly one), so that the sequence b becomes an arithmetic progression, or report that it is impossible.

    It is possible that the resulting sequence contains element equals 0.

    Input

    The first line contains a single integer n (1≤n≤100000) — the number of elements in b.

    The second line contains a sequence b1,b2,…,bn (1≤bi≤10^9).

    Output

    If it is impossible to make an arithmetic progression with described operations, print -1. In the other case, print non-negative integer — the minimum number of elements to change to make the given sequence becomes an arithmetic progression. The only allowed operation is to add/to subtract one from an element (can't use operation twice to the same position).

    input

    1. 4
    2. 24 21 14 10

    output

    3
    

    题意:给定n个数的序列,对于每一个数,可以进行+1,-1,不动,三种操作,注意每个数只能操作一次,问最少需要操作多少次使得整个序列变成等差序列,如果无解输出-1.

    解析等差数列的特点,如果首项和公差知道,那么整个序列就都知道了,因此我们枚举前两项所有的可能,一共九种,对于每种合法情况对答案取min即可。

    1. #include
    2. using namespace std;
    3. const int N=1e5+5;
    4. int a[N],b[N];
    5. int x[9]={0,0,0,1,1,1,-1,-1,-1};
    6. int y[9]={1,0,-1,1,0,-1,1,0,-1};
    7. void solve()
    8. {
    9. int n;
    10. scanf("%d",&n);
    11. for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    12. if(n<=2)//特判一下
    13. {
    14. printf("0\n");
    15. return;
    16. }
    17. int ans=1e9;//设立答案
    18. for(int i=0;i<9;i++)
    19. {
    20. for(int j=1;j<=n;j++) b[j]=a[j];//每种初始拷贝
    21. b[1]+=x[i],b[2]+=y[i];
    22. int k=b[2]-b[1],cnt=0;//cnt记录当前情况所需操作次数
    23. if(x[i]!=0) cnt++;//此处就要累加cnt
    24. if(y[i]!=0) cnt++;
    25. bool ok=true;//此情况是否合法
    26. for(int j=3;j<=n;j++)
    27. {
    28. int c=b[j]-b[j-1]-k;//与前一个差值的差
    29. if(c==0) continue;
    30. else if(c==1) b[j]--,cnt++;
    31. else if(c==-1) b[j]++,cnt++;
    32. else//无解情况
    33. {
    34. ok=false;
    35. break;
    36. }
    37. }
    38. if(ok) ans=min(ans,cnt);
    39. }
    40. if(ans==1e9) ans=-1;
    41. printf("%d\n",ans);
    42. }
    43. int main()
    44. {
    45. int t=1;
    46. //scanf("%d",&t);
    47. while(t--) solve();
    48. return 0;
    49. }
  • 相关阅读:
    ASO优化含义篇:积分墙是什么?
    想要精通算法和SQL的成长之路 - 至少有 K 个重复字符的最长子串
    Windows 下载编译chromium源码
    Spring Boot中JSON的数据结构和交互讲解以及实战(超详细 附源码)
    Spring.Boot Web 模板引擎和首页为什么默认的是index.html页面呀《课时十》
    如何使用VMware12PRO安装Mac OS
    Arcgis快速计算NDVI
    Python垃圾回收和GC模块
    .Net 8与硬件设备能碰撞出怎么样的火花(使用ImageSharp和Protobuf协议通过HidApi与设备通讯)
    dp练习2
  • 原文地址:https://blog.csdn.net/qq_63739337/article/details/132737405