7-6 非专8 均分硬币(前缀和)

题目:

有 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值