P1031 [NOIP2002 提高组] 均分纸牌

//URL:https://www.luogu.com.cn/problem/P1031
/*
有 NN 堆纸牌,编号分别为 1,2,…,N1,2,…,N。每堆上有若干张,但纸牌总数必为 NN 的倍数。可以在任一堆上取若干张纸牌,然后移动。
移牌规则为:在编号为 11 堆上取的纸牌,只能移到编号为 22 的堆上;在编号为 NN 的堆上取的纸牌,只能移到编号为 N−1N−1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。
现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。
例如 N=4N=4 时,44 堆纸牌数分别为 9,8,17,69,8,17,6。

1、纸牌一定可以分到一样多。(题目条件)
2、相邻两堆牌间最多只会移动纸牌一次。(最优方案)
每次移动可以看作相邻两堆中左边一堆i往右边一堆i+1移动x张
1)x>0 左往右移动1次
2)x<0 右往左移动1次
3)x=0 不移动。当且仅当此时牌堆1-i总牌数为i*总平均数张(牌堆1-i在之前的交换中纸牌总数保持不变)

*/
/*
4
9 8 17 6

3


*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<queue>
#include<vector>
#include<bits/stdc++.h>
typedef long long ll;
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=1e1 +10;
const int mod=998244353;
const int inf=0x3f3f3f3f;

int a[222],n,ave,ans;

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],ave+=a[i];
    ave/=n;
    for(int i=1;i<n;i++){
        a[i]-=ave;
        if(a[i]!=0)
        {
            ans++;
            a[i+1]+=a[i];
        }
    }
    cout<<ans<<'\n';
    
    return 0;
}

 

posted @ 2023-12-31 16:26  JMXZ  阅读(20)  评论(0)    收藏  举报