【Luogu1031】均分纸牌

Source and Judge

NOIP2002 提高组 T1
Luogu1031
Caioj1508

Problem

【Brief description】
有N堆纸牌,编号分别为 1,2,…… , N。
每堆上有若干张,但纸牌总数必为 N 的倍数。
可以在任一堆上取若于张纸牌,然后移动。

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

现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。
【Input】
N(N 堆纸牌)
A1 A2 …… An (N 堆纸牌,每堆纸牌初始数)
【Output】
所有堆均达到相等时的最少移动次数。
【Limited conditions】
1 <= N <= 100
1 <= Ai <= 10000
【Sample input】
4
9 8 17 6
【Sample output】
3
【Sample explanation】

1
2
3
4
5
6
N=4,4堆纸牌数分别为:
(1) 9 (2) 8 (3) 17 (4) 6
移动3次可达到目的:
从 (3) 取 4 张牌放到 (4)(9 8 13 10) ->
从 (3) 取 3 张牌放到 (2)(9 11 10 10) ->
从 (2) 取 1 张牌放到 (1)(10 10 10 10)


Record

30min

Analysis1

请先思考后再展开

显然我的贪心很菜

首先,显然我们要与平均数比较,所以可以直接全部减去平均数
那么把方向固定,以从左到右为例,对于i,前面i-1个已经解决【不一定是顺序上的】
因为只能相邻操作,才保证了这种做法的正确性,总会有与i+1交互的过程
那么自己不平衡的时候,步数+1,转移不平衡即可

Code1

请先思考后再展开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//Zory-2018
//*******************头文件******************
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#ifdef WIN32
#define BIGN "%I64d"
#else
#define BIGN "%lld"
#endif
using namespace std;
typedef long long ll;
int mymax(int x,int y) {return x>y?x:y;}
int mymin(int x,int y) {return x<y?x:y;}
//*******************全局常量****************
//*******************全局定义****************
int a[110];
//*******************实现******************
//*******************主函数******************
int main()
{
int n;scanf("%d",&n);
int sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
sum/=n;
int ans=0;
for(int i=1;i<=n;i++)
{
a[i]-=sum;
if(a[i]!=0)
{
ans++;
a[i+1]+=a[i];
}
}
printf("%d",ans);
}

本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
本文地址:http://zory.ink/posts/24a0.html
转载请注明出处,谢谢!