题解
【基础】均分纸牌
1 条题解
-
0
解题思路
n 堆纸牌排成一行,总数是 n 的倍数,要通过移动让每堆张数相同,求最少移动次数。
思路:贪心,从左到右处理。
- 先算平均值 avg = 总和 ÷ n
- 从左到右看每一堆:
- 如果这堆少于平均值,就从下一堆借来补齐
- 如果这堆多于平均值,就把多出的放到下一堆
- 等于平均值就不用动
- 每发生一次移动就计数
为什么这样移动次数最少? 从左到右,每一堆只跟下一堆互动,每堆最多操作一次,不会来回搬,次数自然最少。
举例:4 堆 3 5 4 8,平均 5
- 第1堆3,从第2堆借2 → 5 3 4 8(1次)
- 第2堆3,从第3堆借2 → 5 5 2 8(1次)
- 第3堆2,从第4堆借3 → 5 5 5 5(1次)
- 共 3 次
参考代码
#include <iostream> using namespace std; int a[1005]; int main() { int n, sum = 0, avg, s = 0; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; sum += a[i]; } avg = sum / n; for (int i = 1; i <= n; i++) { if (a[i] < avg) { a[i + 1] -= (avg - a[i]); // 从下一堆借 s++; } else if (a[i] > avg) { a[i + 1] += (a[i] - avg); // 多出的给下一堆 s++; } } cout << s << endl; return 0; }复杂度分析
- 时间复杂度:O(N),从左到右一遍
- 空间复杂度:O(N),存纸牌数
- 1