酷代码 AI
菜单
服务商

有 𝑁 堆纸牌,编号分别为 1 , 2 , … , 𝑁 。每堆上有若干张,但纸牌总数必为 𝑁 的倍数。可以在任一堆上取若干张纸牌,然后移动。 移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 𝑁 的堆上取的纸牌,只能移到编号为 𝑁 − 1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。 现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。 例如 𝑁 = 4 时, 4 堆纸牌数分别为 9 , 8 , 17 , 6 。 移动 3 次可达到目的: - 从第三堆取 4 张牌放到第四堆,此时每堆纸牌数分别为 9 , 8 , 13 , 10 。 - 从第三堆取 3 张牌放到第二堆,此时每堆纸牌数分别为 9 , 11 , 10 , 10 。 - 从第二堆取 1 张牌放到第一堆,此时每堆纸牌数分别为  10 , 10 , 10 , 10 。 输入 第一行共一个整数 𝑁 ,表示纸牌堆数。   第二行共 𝑁 个整数 𝐴 1 , 𝐴 2 , ⋯ , 𝐴 𝑁 ,表示

问题分析 纸牌总数为 \( N \) 的倍数,设平均每堆应有 \( \text{avg} \) 张牌。 从左到右处理每堆牌,计算当前堆与平均值的差值,差值不为零时需移动一次。 移动时,将差值累加到下一堆,表示从当前堆移出或移入牌到相邻堆。 算法步骤 1. 计算平均值 \( \text{avg} = \frac{\sum_{i=1}^N A_i}{N} \)。 2. 初始化移动次数 \( \text{steps} = 0 \),当前差值 \( \text{diff} = 0 \)。 3. 遍历每堆牌 \( i \) 从 1 到 \( N \): - 计算当前堆与平均值的差值:\( \text{diff} += A[i] - \text{avg} \)。 - 若 \( \text{diff} \neq 0 \),则移动次数加一。 4. 输出移动次数。 代码实现 ```cpp #include <iostream> using namespace std; int main() { int N; cin >> N; int A[105]; int sum = 0; for (int i = 0; i < N; i++) { cin >> A[i]; sum += A[i]; } int avg = sum / N; int steps = 0; int diff = 0; for (int i = 0; i < N; i++) { diff += A[i] - avg; if (diff != 0) { steps++; } } cout << steps << endl; return 0; } ``` 样例验证 输入: ``` 4 9 8 17 6 ``` 平均值 \( \text{avg} = (9+8+17+6)/4 = 10 \)。 遍历过程: - \( i=0 \): diff = 9-10 = -1, diff ≠ 0, steps=1 - \( i=1 \): diff = -1 + (8-10) = -3, diff ≠ 0, steps=2 - \( i=2 \): diff = -3 + (17-10) = 4, diff ≠ 0, steps=3 - \( i=3 \): diff = 4 + (6-10) = 0, diff = 0, steps 不变 输出:3 时间复杂度 \( O(N) \),满足数据范围要求。 [2026-01-11 12:41:21 | AI问答 | 563点数解答]

相关提问
发财导航,免费问AI
实用工具查看更多