AcWing 4780. 等差数列「掘金日新计划 · 12 月更文挑战」

85 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第30天,点击查看活动详情

AcWing 4780. 等差数列

题目描述

给定一个长度为 n 的正整数数列 a1,a2,…,an 和一个正整数 k。

你可以对数列进行以下两种操作:

  • + i x,增加操作,将 ai 的值增加 x(x≥1)。
  • - i x,减少操作,将 ai 的值减少 x(x≥1)。

要求:在任何时候,你都需要保证每个 ai 的值都是正整数

请你使用尽可能少的操作次数,使得数列能够满足:对于所有 i(1≤i<n),ai+1−ai=k 均成立。

请你输出所需要的最少操作次数以及对应的具体操作方案。

输入格式

第一行包含两个整数 n,k。

第二行包含 nn 个整数 a1,a2,…,an。

输出格式

第一行输出一个整数 p,表示所需要的最少操作次数。

接下来 p 行,用来输出具体操作方案,每行输出一个具体操作 + i x 或 - i x。你需要保证输出的 i 和 x 均为正整数,且 1≤i≤n。

如果最少操作次数的方案不唯一,则输出任意一种方案均可。

数据范围

前 33 个测试点满足 1≤n≤7。
所有测试点满足 1≤n≤1000,1≤k≤1000,1≤ai≤1000。

输入样例1:

4 1
1 2 1 5

输出样例1:

2
+ 3 2
- 4 1

输入样例2:

4 1
1 2 3 4

输出样例2:

0

输入样例3:

7 1
1 1 2 3 4 5 6

输出样例3:

6
+ 2 1
+ 3 1
+ 4 1
+ 5 1
+ 6 1
+ 7 1

思路

其实这个题最简单的方法就是暴力,列举数组中的数据,记录下当前数据满足题目条件需要的操作次数,最后对比一下,输出最小操作次数和具体的操作步骤。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
int n,k;
const int N=2e5+10;
int a[N];
int op(int x){
    int res=0;
    for(int i=1;i<=n;i++){
        if(a[x]-a[i]!=k*(x-i)&&a[x]-k*(x-i)>0)res++;
        if(a[x]-a[i]!=k*(x-i)&&a[x]-k*(x-i)<=0)return 0x3f3f3f3f;
    }
    return res;
}
signed main(){
    IOS;
    cin>>n>>k;
    for(int i=1;i<=n;i++)cin>>a[i];
    int x=1;
    for(int i=2;i<=n;i++){
        if(op(x)>op(i))x=i;
    }
    cout<<op(x)<<endl;
    for(int i=1;i<=n;i++){
        if((a[x]-a[i])!=k*(x-i)){
            if(a[x]>a[i]+k*(x-i))cout<<"+"<<" "<<i<<" "<<a[x]-(a[i]+k*(x-i))<<endl;
            else if(a[x]<a[i]+k*(x-i))cout<<"-"<<" "<<i<<" "<<(a[i]+k*(x-i))-a[x]<<endl;
        }
    }
    return 0;
}