题目描述:P1031 [NOIP2002 提高组] 均分纸牌
解题思路
解题思路
1、假设纸牌数可以为负数,那么对于每一堆纸牌,缺少的牌就向右侧的堆索要(即使使其变为负数),多出的牌就送到右边的堆中,此时至多操作 $n-1$ 次将满足题意
2、由于一次操作可以运送任意数量的牌,简单猜想证明可知:假设上面情况需要 $m$ 次操作,一定存在某种方案,通过调整操作顺序,使得这 $m$ 次操作合法(不出现负数)
3、简单举例,共 $3$ 堆牌,每堆牌数量分别为 $\{ 1, 1, 7 \}$,易知平均为 $3$。对于第 $1$ 堆牌,向右索要 $2$ 张,此时变为 $\{ 3, -1, 7 \}$;对于第 $2$ 堆牌,向右索要 $4$ 张,变为 $\{ 3, 3, 3 \}$满足题意。同时通过调整操作顺序一定能使得操作合法,例如该例可先执行操作 $2$ 再执行操作 $1$,即使得操作合法,其他例子也可猜想得证
4、所以不需要考虑负数的问题,按照上面的方法模拟即可
代码实现
代码实现
#include <bits/stdc++.h> using namespace std; const int N = 110; int a[N]; void solve() { int n; cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; int sum = 0; for (int i = 1; i <= n; i++) sum += a[i]; int avg = sum / n; int ans = 0; for (int i = 1; i <= n; i++) { if (a[i] < avg) { int k = avg - a[i]; a[i] += k; a[i + 1] -= k; ans++; } else if (a[i] > avg) { int k = a[i] - avg; a[i] -= k; a[i + 1] += k; ans++; } } cout << ans; } int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int T = 1; // cin >> T; while (T--) solve(); return 0; }
如果较为紧急,建议添加微信或QQ,并注明来意
评论系统可能加载较慢,请耐心等待或刷新重试