【洛谷】均分纸牌+贪心算法

【洛谷】均分纸牌+贪心算法

题目描述
有NN堆纸牌,编号分别为 1,2,…,N1,2,…,N。每堆上有若干张,但纸牌总数必为NN的倍数。可以在任一堆上取若干张纸牌,然后移动。

移牌规则为:在编号为11堆上取的纸牌,只能移到编号为22的堆上;在编号为NN的堆上取的纸牌,只能移到编号为N-1N−1的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。

现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。

例如N=4N=4,44堆纸牌数分别为:

①99②88③1717④66

移动33次可达到目的:

从 ③ 取44张牌放到 ④ (9,8,13,109,8,13,10)-> 从 ③ 取33张牌放到 ②(9,11,10,109,11,10,10)-> 从 ② 取11张牌放到①(10,10,10,1010,10,10,10)。
输入格式
两行
第一行为:NN(NN 堆纸牌,1 \le N \le 1001≤N≤100)
第二行为:A1,A2, … An(NN堆纸牌,每堆纸牌初始数,1 \le A_i \le 100001≤Ai≤10000)
输出格式
一行:即所有堆均达到相等时的最少移动次数。
输入样例
4
9 8 17 6
输入样例
3

相信有的人会觉得这个题很难或者不好写,代码会很长。但是!!这个题和求A+B差不多哦 先看一下简短代码加强信心

#include
using namespace std;
int n,a[101],mid,all,ans;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i],all+=a[i];
    all/=n;
    for(int i=1;i<=n;i++)if(a[i]-all)
    a[i+1]+=a[i]-all,ans++;
   cout<

对,你没看错,就是这么简短 下面给思路

从第一堆牌开始,如果正好等于平均那么不用动,次数不加,而当他多或少于平均,那么这部分只能由下一堆给他,多既是正少既是负,这个差值会给下一堆,然后下一堆又找下下一堆判断,这样不会重复也是最少移动法
题例
平均aver数为10
1.差为-1 第一堆变成aver 10 ,第二堆加差
10,7,17,6 ans=1
2.差为 -3,第二堆aver ,第三堆加差
10,10,14,6 ans=2;
3.差为4 第三堆aver 第四堆加差
10,10,10,10 ans=3
祝各位尽快AC

#include
using namespace std;
int main()
{
	int n,a[100],aver=0,ans=0;
	cin>>n; 
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		aver+=a[i];	
	}
	aver/=n;
	for(int i=1;i<=n;i++)
	{
		if(a[i]-aver)
		{
			a[i+1]+=a[i]-aver;
			ans++;
		}
	}
	cout<

你可能感兴趣的:(贪心算法,算法)