题目:
有 N 堆硬币,编号分别为 1,2,…,N。每堆中都有若干枚相同的硬币,题目保证所有硬币的总数为 N 的倍数。可以在任意一堆中取若枚硬币,然后移动到另一堆中。
现在要求在编号为 1 堆中取的硬币,只能移到其右边的堆中;在编号为 N 的堆中取的硬币,只能移到其左边的堆中;在其他堆中取的硬币,可以移到相邻左边或右边的堆中。请你找出一种移动方法,用最少的移动次数使每堆中硬币数都一样多。
输入格式:
第一行一个整数 N,表示硬币堆数。第二行 N 个整数,分别表示每堆纸牌初始时的纸牌数。
输出格式:
共一行,即所有堆均达到相等时的最少移动次数。
输入样例:
4
9 8 17 6
输出样例:
3
解题思路:
先把每一项在减去均值,在求前缀和把不为零的情况加起来
AC代码:
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include<iostream>
#include<string>
#include<cmath>
#include<vector>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<list>
#include<cstdlib>
using namespace std;
#define arrout(a,n) rep(i,1,n)std::cout<<a[i]
#define arrin(a,n) rep(i,1,n)std::cin>>a[i]
#define _for(i,a,b) for( int i=(a); i<(b); ++i)
#define _rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define _dep(i,a,b) for( int i=(a); i>=(b); --i)
#define mem(a,x) memset(a,x,sizeof a)
#define all(x) x.begin(),x.end()
#define arrall(a,n) a+1,a+1+n
#define PII std::pair<int,int>
#define m_p std::make_pair
#define endl '\n'
#define ff first
#define ss second
#define CD const double
#define CI const int
#define int long long
#define itn int
#define PI 3.14159
CI N = 1e9 + 9, MAXI = 0x3f3f3f3f, MINI = -0x3f3f3f3f, MOD = 1e9 + 7;
int dx[] = { 0, 1, 0,-1, 1, 1,-1,-1, 0 };
int dy[] = { 1, 0,-1, 1, 1,-1,-1, 1, 0 };
int n,arr[101],ave,ans;
signed main()
{
//cin.tie(0), cout.tie(0), ios::sync_with_stdio(0);
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> arr[i];
ave += arr[i];
}
ave /= n;
//减去均值
for (int i = 1; i <= n; ++i) arr[i] -= ave;
for (int i = 1; i <= n; ++i)
{
if (arr[i] == 0) continue;
//减去均值后前缀和为0
arr[i + 1] += arr[i];
ans++;
}
cout << ans;
return 0;
}