zoukankan      html  css  js  c++  java
  • 洛谷 P1031 均分纸牌【交叉模拟】

    题目描述

    有 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)。

    输入输出格式

    输入格式:

    键盘输入文件名。文件格式:

    N(N 堆纸牌,1 <= N <= 100)

    A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000)

    输出格式:

    输出至屏幕。格式为:

    所有堆均达到相等时的最少移动次数。

    输入输出样例

    输入样例#1: 复制
    4
    9 8 17 6
    
    输出样例#1: 复制
    3
    【分析】:

    (1)计算出平均纸牌数

    (2)对牌叠预处理(也可以不作处理)

    (3)模拟移牌情况

    (4)输出答案

    因为只能移动相邻的,可以将牌少于avg的把后一个减少(avg - 前一个),计数器++;多于的同理
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define LL long long
    using namespace std;
    int main()
    {
        int n,i,sum=0,ans=0,a[1000];
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
        scanf("%d",&a[i]);
        sum+=a[i];
        }
        sum/=n;//平均值
        for(i=1;i<=n;i++)
        {
            if(a[i]<sum)//多了
            {
                ans++;
                a[i+1]-=(sum-a[i]);
            }
            else
            if(a[i]>sum)//少了
            {
                ans++;
                a[i+1]+=(a[i]-sum);
            }
        }
        printf("%d
    ",ans);
        return  0;
    }
    不预处理模拟
    
    
    
    

    我们可以把平均值设为0,牌数大于平均值的排堆牌数为正数,反之则为负数。

    #include<bits/stdc++.h>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int a[10005];
    const int inf = 0x3f3f3f3f;
    int main()
    {
        int n, sum = 0, Min = inf, Max = -inf, cnt = 0;
        cin >> n;
        for(int i=1; i<=n; i++)
        {
            cin >> a[i];
            sum += a[i];
        }
        int avg = sum / n;
        for(int i=1; i<=n; i++)
        {
            a[i] -= avg;
        }
        for(int i=1; i<=n; i++)
        {
            if(a[i] == 0) continue;
            a[i+1] = a[i+1] + a[i];
            cnt++;
        }
        cout<<cnt<<endl;
    }
    预处理模拟
  • 相关阅读:
    PAT顶级 1024 Currency Exchange Centers (35分)(最小生成树)
    Codeforces 1282B2 K for the Price of One (Hard Version)
    1023 Have Fun with Numbers (20)
    1005 Spell It Right (20)
    1092 To Buy or Not to Buy (20)
    1118 Birds in Forest (25)
    1130 Infix Expression (25)
    1085 Perfect Sequence (25)
    1109 Group Photo (25)
    1073 Scientific Notation (20)
  • 原文地址:https://www.cnblogs.com/Roni-i/p/8728760.html
Copyright © 2011-2022 走看看