NOIP2002[提高组] 均分纸牌 题解

题面

题目保证有解即纸牌总数能被人数整除(N|T)每个人持有纸牌a[1]...a[m],我们可以先考虑第一个人

1.若a[1]>T/M,则第一个人需要给第二个人c[1]-T/M张纸牌,即把c[2]加上c[1]-T/M。

2.若a[1]<T/M,则第一个人需要拿第二个人c[1]-T/M张纸牌,即把c[2]减去T/M-c[1]。

我们可以按照这种方法依次考虑2~M个人。即使某个时刻有某个c[i]被减为负数也没有关系,因为接下来c[i]就会从c[i+1]处拿纸牌。

代码

#include<bits/stdc++.h>
using namespace std;
int m,a[105],T,ans;
int main(){
	scanf("%d",&m);
	for(int i=1;i<=m;++i){
		scanf("%d",&a[i]);
		T+=a[i];
	}
	T/=m;
	for(int i=1;i<=m;++i){
		a[i]-=T;
	}
	for(int i=1;i<=m;++i){
		if(a[i]!=0){
			a[i+1]+=a[i];
			ans++;
		}
	}
	printf("%d",ans);
	return 0;
}

在此问题上还可进行一个拓展,若每次只能拿一张牌,思路也跟上面相同,最小步数就是

\(\sum_{i=1}^M\) \(\mid\)i*T/M-G[i]\(\mid\) ,其中G是a的前缀和,即 G[i]= \(\sum_{j=1}^i\) a[i]

其中的含义是每个“前缀”最初有G[i]张纸牌,最后会有i*T/M张纸牌。

如果我们设A[i]=a[i]-T/M,即一开始就让每个人手中的纸牌数都减去T/M,并且最终让每个人手里都只有0张纸牌,答案依然不变,就是

\(\sum_{i=1}^M\) \(\mid\)S[i]\(\mid\)其中S是A的前缀和即 S[i]=\(\sum_{j=1}^i\)A[i]

posted @ 2019-08-26 20:02  End_donkey  阅读(255)  评论(0编辑  收藏  举报