开启掘金成长之旅!这是我参与「掘金日新计划 · 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;
}