题目链接: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 }