J 分班(class)(NYIST 2019年校赛)


  • J 分班(class)(NYIST 2019年校赛)

内存限制:256MB 时间限制:1s Special Judge: No

题目描述:

jsb 是 XX 市第一中学的校长。一轮模拟考试结束后,jsb 想让所有学生重新分班。

XX 市第一中学共有 n 位学生,其中第 i 个学生的该次模拟考试的成绩为 bi。jsb 打算将所 有学生分配到 m 个班级里,第 i 个班级的人数为 ai,即需要将恰好 ai 个人分配到第 i 个班级 内。

然而,如果班级里的学霸和班级内的其他同学水平差距过大,会使学霸产生自满度。具体 来说,如果第 i 个学生在第 j 个班级中,他的成绩比第 j 个班级的所有其他人的分数最大值 还高,那么的自满度等于他的成绩减去第 j 个班级第二名的成绩;否则他的自满度为 0。

jsb 希望所有学生的自满度的最大值尽量小。请你安排分班方案,使得所有学生自满度的 最大值最小。

例如,假设一共有 10 位学生,他们的成绩分别为 1,2,3,4,5,6,7,8,9,10,现在需要将他们 分到人数分别为 4 和 6 的两个班级内。可以把成绩为 1,2,3,4 的同学分成一个班,成绩为 5,6,7,8,9,10 的同学分成一个班,这样成绩为 4 和 10 的同学自满度为 1,其他同学的自满度 为 0,最大的自满度为 1。显然,最大的自满度不可能小于 1;当然,使自满度最大值为 1 的 分班方法还有其他很多种。

输入描述:

第一行 2 个正整数 n, m (2 ≤ n ≤ 100000, 1 ≤ m ≤ 50000),表示学生人数以及班级的个数。

接下来一行 m 个正整数 a1, a2, ..., am (ai ≥ 2,∑m i=1 ai = n) ,表示每个班级的人数。

接下来一行 n 个正整数 b1, b2, ..., bn (0 ≤ bi ≤ 109),表示每个人的成绩。

输出描述:

一行一个正整数,表示答案,即所有学生的自满度最大值的最小值。

样例输入:

10 2
4 6
1 2 3 4 5 6 7 8 9 10

样例输出:

1

提示:

img

分析:

​ 可以采用二分求解。

下面解释为什么可以使用二分求解

​ 假设答案的所要求的最小值为kkk, 现在测试valmaxvalmaxvalmax为分班后的自满度最大值

  • 如果valmax&lt;kvalmax&lt;kvalmax<k 则不管采用何种方法进行分班肯定不成功的
  • 如果valmax&gt;kvalmax&gt;kvalmax>k,则最优的分班方法可定能成功分班

那么对于一个valmaxvalmaxvalmax怎么去检验该值是否可行?

下面设计一个最优的分班方法:

​ 我们可以将学生成绩从小到大排序,将班级人数从小到大排序,接下来 开始从大到小开始遍历学生成绩,如果挨着的两个学生成绩之差&lt;=valmax&lt;=valmax<=valmax 则将这一对作为某一个班级的前二名,就这样一直下去,直到遍历完所有学生,或者选出的对数已经等于班级个数则退出遍历。下面即开始检验分班人数是否满足.

​ 记录下每对前面可选的人数(还未分到班级的人数)。 可以这样计算:假设班级共mmm个,总共有nnn个人,这一组前面还有iii个人,这是第tottottot对,那么该对下前面未分班的人数为(i−(m−tot))∗2)(i-(m-tot))*2)(i(mtot))2)

​ 按照先前选出对的顺序分别作为第m,m−1,m−2,...1m,m-1,m-2, ...1m,m1,m2,...1个班的前二名 (第mmm班的班级人数最多,第m−1m-1m1的班级人数次多,依此类推)

​ 如果对于第iii个班 可以分够人数,则需要满足下面两点要求

  • ​ 前i个班可以分够人数

  • ​ 如果前i个班的需要塞的人数(即不包括每个班前二名)<=第i个班前二名之前的人数(即还可以塞的人数) ,

    那么则该班可以分够要求的人数。

​ 如果所有的班都可以分够要求的人数,则该maxval可行。

代码:

#include<bits/stdc++.h>
#define mset(a,b)   memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e5+100;
int total[maxn];//班级需要分的人数 从大到小
int frontot[maxn];//从大到小  表示 后面未分班的学生
int score[maxn<<1],book[maxn];
int m,n;
bool cmp(int a,int b)
{
    return a>b;
}
bool Check(int val)
{
/*
1.符合要求的对数,到达m对即可
2.再记下m对前面可以塞的个数
*/
    int tot=0;
    mset(book,0);
    for(int i=n-2;i>=0;--i)
    {
        if(book[i+1]||book[i])
            continue;
        if(score[i+1]-score[i]<=val)
        {
            frontot[tot]=i-(m-tot-1)*2;
            tot++;
            if(tot==m)
                break;
            book[i+1]=book[i]=1;
        }
    }
    if(tot<m)
        return 0;
    int sum=0;
    for(int i=m-1;i>=0;--i)
    {
        sum+=total[i]-2;
        if(frontot[i]<sum)
            return 0;
    }
    return 1;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;++i)
    {
        scanf("%d",total+i);
    }
    for(int i=0;i<n;++i)
        scanf("%d",score+i);
    sort(score,score+n);
    sort(total,total+m,cmp);
    int mid,ans=-1,l,r;
    l=0,r=1e9;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(Check(mid))
        {
            r=mid-1;
            ans=mid;
        }
        else
        {
            l=mid+1;
        }

    }
    printf("%d\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/dchnzlh/p/10546537.html

分班是教学管理中一个重要的环节。如何分班才算平衡?相信很多人都想过这个问题,按总分高低排的方法只分得各班的总平均分基本平衡,但受偶然因素影响一些科目班之间平衡性很差,而学校评价教师教学成绩却以科目班的平衡性评价为主。 因此,我们都希望最好能分得每个科目各班都基本平衡,处理这个问题用手工根本难于做到,只有借助计算机的强大数据处理能力,我们才可能解决这个难题,下面示例数据就是最有力的说明,要观看示例效果请按下红色的[开始分班]键。即使你不用平衡各科分班,本软件也是一个又快又好地辅助分班的好助手。多谢使用本免费软件,并提出宝贵意见。??使用说明:先在表头填上要分开的班数,然后在下面的“要分班的原来学生成绩表”中输入学生的各科的成绩,最后按[开始分班]按钮,稍后你就可以在“结果表”中看到按平衡各科分班结果与按总分分班结果,以及两结果的对比预览表。 注意:1、性别一个字段是必须输入的数据;学号和姓名两个字段可选任一个字段输入,但最好能全部输入。?? 2、性别用“1”表示男,“0”表示女;学号最好能用前面数位表示班别,后两位数表示座号进行编号,以便分班后能方便查出原来所在的班级。?? 3、你最多可以输入19个班,每班77人,6个科目;1463个学生的成绩。科目名称可自行修改。?? 4、各科目的满分成绩不能超过100分,如果超过100分,应先把成绩折为100分,然后输入成绩。 本作者还制作有“教学成绩统计系统”、“课程表编排系统”、“数学工具箱”等软件,全部用EXCEL作为开发平台。????在使用过程中有什么问题,或有什么建议要求,请TET:(0757)8886326或E-mail:lixuedong@peoplemail.com.cn  
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值