2351 - 均分纸牌

通过次数

0

提交次数

0

时间限制 : 1 秒 内存限制 : 125 MB

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

<span style="line-height:1.5;">移牌规则为:在编号为1的堆上取的纸牌,只能移到编号为2的堆上;在编号为N的堆上取的纸牌,只能移到编号为N-1的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。</span> 

<span style="line-height:1.5;">现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。</span> 

<span style="line-height:1.5;">例如N=4,4堆纸牌数分别为:</span> 

① 9 ② 8 ③ 17 ④ 6

&nbsp; &nbsp; &nbsp; 移动3次可达到目的:

从③取4张牌放到④(9 8 13 10)-&gt;从③取3张牌放到②(9 11 10 10)-&gt;从②取1张牌放到①(10 10 10 10)。

<br />

题目输入

每个测试文件只包含一组测试数据,每组输入的第一行输入一个整数N(1<=N<=100),表示有N堆纸牌。

接下来一行输入N个整数A1 A2...An,表示每堆纸牌初始数,1<=Ai<=10000。


题目输出

对于每组输入数据,输出所有堆均达到相等时的最少移动次数。


输入/输出样例

输入格式

4
9 8 17 6

输出格式

3

C语言解答

#include<stdio.h>
int main()
{int and1=0,and2=0,ave=0,i,j=0,n,a[1000]={0};
 scanf("%d",&n);
 for(i=0;i<n;i++)
 {scanf("%d",&a[i]);
 and1+=a[i];}
 ave=and1/n;
 for(i=0;i<n;i++)
 {if(a[i]!=ave)
  {a[i+1]=a[i+1]+a[i]-ave;
  j++;}
}
printf("%d",j);
return 0;
}

C++解答

#include<cstdio>
int main()
{
	int n,a=0,s=0,num[101];
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{scanf("%d",&num[i]);a+=num[i];}
	a/=n;
	for(int i=1;i<=n;i++)
	num[i]-=a;
	int i=1,j=n;
	while(num[i]==0&&i<n)i++;
	while(num[i]==0&&j>1)j--;
	while(i<j)
	{
		num[i+1]+=num[i];
		num[i]=0;
		s++;
		i++;
		while(num[i]==0&&i<j)i++;
	}
	printf("%d",s);
	return 0;
}

Java解答

import java.util.*;
public class Main{
  public static void main(String[] args) {
    Scanner cin = new Scanner(System.in);
    int n = cin.nextInt();
    int dist = 0,cnt = 0,sum = 0;
    int[] arr = new int[n];
    for(int i = 0; i < n; i ++){
      int value = cin.nextInt();
      sum += value;
      arr[i] = value;
    }
    int average = sum/n;
    for(int i = 0; i < n; i ++){
      if(dist != 0){
        cnt += 1;
      }
      arr[i]+=dist;
      dist = arr[i] - average;

    }
    System.out.println(cnt);
  }
}