题目描述
天地无情人有情,一方有难八方支援!汶川大地震发生后,灾区最紧缺的是救灾帐篷,全国各地支援的帐篷正紧急向灾区运送。假设围绕汶川县有环行排列的n个救灾帐篷的存储点,每个存储点存有的帐篷数量分别是M1,M2,......,Mn,且S=M1+M2+......+MN,并必为n的倍数。可以在任意一个存储点中取任意数量的帐篷搬运到相邻的存储点。
现在需要找到一种搬运方法,搬运最少的帐篷使得每个存储点中的帐篷数目相同。
例如:n=5,每个存储点帐篷的数量分别为17 9 14 16 4,我们进行如下搬运:
(1)存储点①向存储点②搬运1个帐篷;
(2)存储点①向存储点⑤搬运4个帐篷;
(3)存储点③向存储点②搬运2个帐篷:
(4)存储点④向存储点⑤搬运4个帐篷。
搬运帐篷的总数是1+4+2+4=11,并且可以证明这是最佳搬运方法。
输入格式
第一行,一个整数n(n≤10000),表示有n个存储点;
第二行,n个整数(整型范围),表示n个存储点中帐篷数量。
输出格式
一个整数,表示最少搬运的帐篷数量。
输入样例
5
17 9 14 16 4
输出样例
11
题解
可以看出题目中给出的数据是环形的,那我们枚举断边使其变成线性,这样这题就变成了“均分纸牌”了。
#include <iostream> #include <cmath> #define MAXN 20002 using namespace std; int n; int a[MAXN]; int b[MAXN]; int l, r; int sum; int num; int ans = 2147483647; int main() { cin >> n; for(register int i = 1; i <= n; i++) { cin >> a[i]; sum += a[i]; } sum /= n; for(register int i = 1; i <= n; i++) { a[i] -= sum; a[i + n] = a[i]; } for(register int i = 1; i <= n; i++) { num = 0; l = i; r = i + n - 1; for(register int j = l; j <= r; j++) { b[j] = a[j]; } while(l < r) { if(!b[l]) { l++; continue; } num += abs(b[l]); b[l + 1] += b[l]; b[l] = 0; } if(num < ans) ans = num; } cout << ans; return 0; }
参考程序
原文地址:https://www.cnblogs.com/kcn999/p/10800540.html
时间: 2024-10-07 12:23:47