酷代码 AI
菜单
全部AI  /  热门  /  AI写代码神器
服务商

给定长为 n 的整数序列 a。 您可以对这个序列进行若干次(可以为 0 次)操作,每次操作形如: 选定满足 1≤i,j≤n 的下标 i 和 j,将 a i​赋值为 a i​+1,同时将 a j​赋值为 a j​−1。i 和 j 不能相同。 求使得前缀和之和等于后缀和之和的最小操作次数。 也就是说,令 s i​=a 1​+a 2​+⋯+a i​,t i​=a i​+a i+1​+⋯+a n​,有 s 1​+s 2​+⋯+s n​=t 1​+t 2​+⋯+t n​。 注意,a i​可以变为负数。 输入格式 第一行一个整数 n。 第二行用空格隔开的 n 个整数,表示 a 序列。 输出格式 输出一行一个整数表示最小操作次数。 若无解,输出 −1。c++

这个问题需要找到使前缀和之和等于后缀和之和的最小操作次数。关键在于理解操作的性质和目标条件的数学表达。 分析 1. 操作性质:每次操作将某个元素加1,另一个元素减1,保持总和不变。 2. 前缀和之和(S):S = s₁ + s₂ + ... + sₙ = Σ (n - k + 1) * aₖ 3. 后缀和之和(T):T = t₁ + t₂ + ... + tₙ = Σ k * aₖ 4. 目标条件:S = T ⇒ Σ (n - k + 1 - k) * aₖ = 0 ⇒ Σ (n - 2k + 1) * aₖ = 0 解法 1. 计算初始的 Σ (n - 2k + 1) * aₖ 2. 若初始值已为0,则操作次数为0 3. 否则,检查是否有解: - 操作可以调整元素值,但总和不变 - 需要存在至少两个元素可以调整(一个加,一个减) 4. 最小操作次数等于 |Σ (n - 2k + 1) * aₖ| / 2(每次操作可改变该值最多2) C++代码 ```cpp #include <iostream> #include <vector> #include <cmath> using namespace std; int main() { int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; ++i) { cin >> a[i]; } long long sum = 0; for (int k = 1; k <= n; ++k) { sum += (n - 2 * k + 1) * a[k - 1]; } if (sum == 0) { cout << 0 << endl; } else if (n < 2) { cout << -1 << endl; } else { cout << abs(sum) / 2 << endl; } return 0; } ``` 注意事项 1. 当n=1时,无法进行操作(需要i≠j),直接输出-1 2. 总和的计算可能溢出,使用long long类型 3. 操作次数是绝对值的一半,因为每次操作可以改变总和最多2(一个加1,一个减1) [2025-05-25 17:27:47 | AI写代码神器 | 532点数解答]

相关提问