zoukankan      html  css  js  c++  java
  • 洛谷【P1109 学生分组】 题解

    题目描述

    有N组学生,给出初始时每组中的学生个数,再给出每组学生人数的上界RR和下界L(L le R)L(LR),每次你可以在某组中选出一个学生把他安排到另外一组中,问最少要多少次才可以使NN组学生的人数都在[L,R][L,R]中。

    输入格式

    第一行一个整数NN,表示学生组数; n le 50n50

    第二行NN个整数,表示每组的学生个数;

    第三行两个整数L,RL,R,表示下界和上界。

    输出格式

    一个数,表示最少的交换次数,如果不能满足题目条件输出-11

    题解:

    首先考虑一下什么时候才能满足所有组的人数都在区间[L,R]

    1)人数最少:当所有组的人数都为L时,总人数最少,此时总人数=L * N

    2)人数最多:当所有组的人数都为R时,总人数最少,此时总人数=R * N

    所以只有在 L * N <=总人数<= R * N 时,才能满足题意,否则输出-1。下面分析一下满足题意的情况:

    考虑人数多于R的小组,令X=这些小组比人数上限R多的总人数,要想满足人数在区间[L,R]内,必须把这X个人都**转出**到其他小组,所以 交换次数>=X。

    考虑人数小于L的小组,令Y=这些小组比人数下限L少的总人数,要想满足人数在区间[L,R]内,必须其他组的Y个人**转入**到这几个小组,所以 交换次数>=Y。

    接下来考虑X、Y的大小关系对结果的影响。

    1)X>Y,先把X个学生从人数多于R的小组拿出来,把其中Y个学生分配给人数小于L的小组。然后把剩下的X-Y个学生再随便分配即可让所有小组都在区间[L,R](想想为什么不会有多于R的情况)。

    2)X=Y,把X个学生从人数多于R的小组拿出来全部转入人数小于L的小组即可。

    3)X<Y,把X个学生从人数多于R的小组拿出来,全部转入人数小于L的小组。然后在满足人数在[L,R]的前提下从其他小组取出Y-X个学生转入小于L的小组即可。(想想为什么不会有少于L的情况)。

    所以无论哪种情况,max(X,Y)就是最终的交换次数。

    代码如下:
    ```cpp
    #include<bits/stdc++.h>
    using namespace std;
    int n,m=0,b=0,c=0,a[51],l,r;
    int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    cin>>a[i];
    m=m+a[i]; //m计算总人数
    }
    cin>>l>>r;
    if(n*r<m||m<n*l)
    cout<<-1; //如果n*r小于总人数或者n*l大于总人数输出-1
    else{
    for(int i=1;i<=n;i++){
    if(a[i]<l)
    b=l-a[i]+b;
    if(a[i]>r)
    c=a[i]-r+c;
    }
    cout<<max(b,c);
    }
    }
    ```

  • 相关阅读:
    log4net:ERROR XmlHierarchyConfigurator: Cannot find Property [File] to set object on [TF.Log.FileAppender]
    HTTP状态码总结
    基于.NET平台常用的框架整理
    WPF中查看PDF文件之MoonPdfLib类库
    查看操作系统报异常的地方
    VS 附加到进程 加载“附加进程”弹窗很慢
    C# for循环或者foreach往List中添加对象的时候前面的数据总被最后加入的覆盖
    方法的执行过程
    模拟IDE上的run过程
    Java动态加载
  • 原文地址:https://www.cnblogs.com/lau1997/p/12498010.html
Copyright © 2011-2022 走看看