问题描述
小蓝在无聊时随机生成了一个长度为 n 的整数数组,数组中的第 i 个数为 ai,他觉得随机生成的数组不太美观,想把它变成回文数组,也是就对于任意 i∈[1,n], 满足 ai=an−i+1。小蓝一次操作可以指定相邻的两个数,将它们一起加 1 或减 1;也可以只指定一个数加 1 或减 1,请问他最少需要操作多少次能把这个数组变成回文数组?
输入格式
输入的第一行包含一个正整数 n 。
第二行包含 n 个整数a1,a2,⋯,an,相邻整数之间使用一个空格分隔。
输出格式
输出一行包含一个整数表示答案。
样例输入
4
1 2 3 4
样例输出
3
样例说明
第一次操作将 a1,a2a1,a2 加 11,变为 2,3,3,42,3,3,4 ;
后面两次操作将 a1a1 加 11,变为 4,3,3,44,3,3,4 。
评测用例规模与约定
对于 20% 的评测用例, 1≤n≤10;
对于所有评测用例, 1≤n≤10^5,−10^6≤ai≤10^6 。
运行限制
语言 | 最大运行时间 | 最大运行内存 |
---|---|---|
C++ | 1s | 256M |
C | 1s | 256M |
Java | 3s | 512M |
Python3 | 10s | 512M |
PyPy3 | 3s | 512M |
Go | 5s | 512M |
JavaScript | 5s | 512M |
代码实现
#include <bits/stdc++.h>
using namespace std;
const int N = 100100; // 定义数组的最大长度
long long a[N], b[N], sum = 0; // a为输入数组,b用于存储差值,sum用于累加操作次数
int main() {
int n;
cin >> n; // 输入数组的长度
for (int i = 1; i <= n; i++)
cin >> a[i]; // 输入数组元素
// 计算对称位置的差值,b[i] = a[n-i+1] - a[i]
for (int i = 1; i <= n / 2; i++)
b[i] = a[n - i + 1] - a[i];
// 计算最小操作次数
for (int i = 1; i <= n / 2; i++) {
sum += abs(b[i]); // 累加绝对差值到sum
// 尝试通过某种方式减少后续操作,但这里的逻辑有些复杂且不必要
// 原始逻辑似乎尝试通过调整b[i+1]来优化,但这不是标准的回文调整方法
if (b[i] * b[i + 1] > 0) { // 如果b[i]和b[i+1]同号
if (abs(b[i + 1]) > abs(b[i]))
b[i + 1] -= b[i]; // 试图减少b[i+1]的绝对值
else
i++; // 跳过下一个元素(这个逻辑在标准解法中不常见)
}
}
cout << sum; // 输出最小操作次数
return 0;
}