練習賽8.2.均分紙牌

均分紙牌

Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 13 Accepted Submission(s) : 6

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

有 N 堆紙牌,編號分別爲 1,2,…, N。每堆上有若干張,但紙牌總數必爲 N 的倍數。可以在任一堆上取若干張紙牌,然後移動。
移牌規則爲:在編號爲 1 堆上取的紙牌,只能移到編號爲 2 的堆上;在編號爲 N 的堆上取的紙牌,只能移到編號爲 N-1 的堆上;其他堆上取的紙牌,可以移到相鄰左邊或右邊的堆上。
現在要求找出一種移動方法,用最少的移動次數使每堆上紙牌數都一樣多。
例如 N=4,4 堆紙牌數分別爲: ① 9 ② 8 ③ 17 ④ 6
移動3次可達到目的:
從 ③ 取4張牌放到④(9 8 13 10)->從③取3張牌放到 ②(9 11 10 10)-> 從②取1張牌放到①(10 10 10 10)。

Input

輸入有多組數據,每組數據有兩行,第一行爲 N(N 堆紙牌,1 <= N <= 100),第二行爲每堆紙牌的初始
數 A1 A2 … An (l<= Ai <=10000),輸入以N爲0結束。

Output

對於每組數據,所有堆均達到相等時的最少移動次數。

Sample Input

4
9 8 17 6
0

Sample Output

3
思路分析:本題的重點在於要弄明白題目的意思,這個題目可以用遞規也可以用循環,本人是分兩邊來寫的,當從第一個開始因爲它只能於後面那個進行處理,然後是最後面的只能從前面的處理,分兩種情況,一種比平均數大一種比平均數小。
代碼:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
    int n,a[240],s1,sum,count,i;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        sum=0;
        count=0;
        memset(a,0,sizeof(a));
        for(i=1; i<=n; i++)
            scanf("%d",&a[i]);
        for(i=1; i<=n; i++)
        {
            sum+=a[i];
        }
        s1=sum/n;
        for(i=1; i<=n/2; i++)
        {
            if(a[i]>s1)
            {
                a[i+1]+=a[i]-s1;
                a[i]=s1;
                count++;
            }
            else if(a[i]<s1)
            {
                a[i+1]-=(s1-a[i]);
                a[i]=s1;
                count++;
            }
            if(a[n-i+1]>s1)
            {
                a[n-i]+=a[n-i+1]-s1;
                a[n-i+1]=s1;
                count++;
            }
            else if(a[n-i+1]<s1)
            {
                a[n-i]-=(s1-a[n-i+1]);
                a[n-i+1]=s1;
                count++;
            }
        }


        printf("%d\n",count);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章