p1031  均分纸牌

    科技2022-07-15  116

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

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

    现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。

    例如N=4,4堆纸牌数分别为:

    ①9②8③17④6

    移动33次可达到目的:

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

    输入格式 两行

    第一行为:N(N 堆纸牌,1≤N≤100)

    第二行为:A1,A2,A3,A3……

    输入 4 98 17 6 输出 3

    思路: 1 : 每堆牌减去平均数,求每堆牌多了多少或少了多少 2 : 由于牌只可以从相邻牌组中拿到或拿给, 3: 假设 有-3, 4两堆牌,将-3 拿给 4 或将 4拿给-3 .得到的结果都是一样0 1,操作次数同为1. 所以拿牌顺序可以设置为将左边的牌拿给右边的 4. 由于a[0]左边没有牌,所以无法给他牌,直接判断a[0]是不是为0. 为0不需要进行拿牌或去牌操作,若为不为0时,大于0就给右边牌堆a[0]张牌凑成0,小于零也给右牌堆a[0]张牌(根据思路3), 相应a[1]=a[1] + a[0], 依次类推

    #include<stdio.h> #include<stdlib.h> int a[105]; int main() { int n,i,s=0; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d",&a[i]); s += a[i]; } s = s/n; for(i=0;i<n;i++) a[i] -= s; int ans=0; for(i=0;i<n;i++) { if(a[i]==0) continue; else ans++; a[i+1]+=a[i]; } printf("%d",ans); }
    Processed: 0.009, SQL: 8