codeforces 440B. Balancer 解题报告

题目链接:http://codeforces.com/problemset/problem/440/B

题目意思:给出 n 个数,求出这 n 个数的平均值avg,问对于这 n 个数里面中的每一个数,要变为avg 至少需要向相邻的数交换多少次。每次交换只能向相邻的数取1(+1 或者 -1)

    一开始想错了,以为每个数直接跟avg比较,求出它们的差值就是答案。后来关电脑在床上的时候就想到了正确的解法。因为考虑到今天有正式的比赛,所以不像那天又继续奋斗了(累~~~),早上一早验证,果然是对的^_^

    正确的解法是:与avg比较之后,这会影响到旁边的数!!!可以按着某一个顺序来处理,比如从左到右。那么假如处理到第 i 位的数ai,如果它比avg要小,由于最终就是要令ai变成avg,那么求出它跟avg的差cha = avg-ai,注意:这个差是来源于它右边的数a[i+1]的!因此a[i+1]需要减去这个cha,即a[i+1] -= cha。如果ai比avg要大,则cha = ai-avg,a[i+1] += cha。而统计次数是通过不断将 cha 相加来求得的。

      个人感觉像模拟多过像贪心咯~~~

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 #define LL long long
 9 const int maxn = 50000 + 4;
10 LL a[maxn];
11 LL sum;
12 
13 int main()
14 {
15     int n;
16     while (scanf("%d", &n) != EOF)
17     {
18         sum = 0;
19         for (int i = 1; i <= n; i++)
20         {
21              scanf("%lld", &a[i]);
22              sum += a[i];
23         }
24         LL avg = sum / n;
25         LL cnt = 0;
26 
27         for (int i = 1; i < n; i++)
28         {
29             if (a[i] <= avg)
30             {
31                 cnt += avg-a[i];
32                 a[i+1] -= (avg-a[i]);
33             }
34             else
35             {
36                 cnt += a[i]-avg;
37                 a[i+1] += (a[i]-avg);
38             }
39         }
40         printf("%lld
", cnt);
41     }
42     return 0;
43 }
原文地址:https://www.cnblogs.com/windysai/p/3766858.html