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

提示:

分析:

​可以采用二分求解。

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

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

如果valmax<kvalmax<kvalmax

如果valmax>kvalmax>kvalmax>k,则最优的分班方法可定能成功分班

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

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

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

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

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

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

​前i个班可以分够人数

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

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

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

代码:

#include

#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

return 0;

int sum=0;

for(int i=m-1;i>=0;--i)

{

sum+=total[i]-2;

if(frontot[i]

return 0;

}

return 1;

}

int main()

{

scanf("%d%d",&n,&m);

for(int i=0;i

{

scanf("%d",total+i);

}

for(int i=0;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;

}

java 分班_J 分班(class)(NYIST 2019年校赛)相关推荐

  1. 场景:一个年级,相当链表A ,该年级5个班,每个班5个人,相当于链表B1--B5:做一个学生成绩管理系统学生成绩有语文 数学 英语功能: 录入成绩 找三科总分的最高分 最低分 算出平均分

    #include <stdio.h> #include <stdlib.h>struct Student//学生结构体 {char* name;int chinese;int ...

  2. 基于JAVA医院医护人员排班系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署

    基于JAVA医院医护人员排班系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署 基于JAVA医院医护人员排班系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署 本源码技术栈: ...

  3. mysql分表全局查询_mysql如何查询多样同样的表/sql分表查询、java项目日志表分表的开发思路/按月分表...

    之前开发的一个监控系统,数据库的日志表是单表,虽然现在数据还不大并且做了查询sql优化,不过以后数据库的日志表数据肯定会越来越庞大,将会导致查询缓慢,所以把日志表改成分表,日志表可以按时间做水平分表, ...

  4. java 交易金额转换分,java金额元与分转换工具种

    java金额元与分转换工具类 java金额元与分转换的一个工具类. 1.元转分: 可传入字符串或者long型(隐式转换为long型也可)整数. 若传入为字符串,则通过替换小数点的方式转换,小数点有多位 ...

  5. 张浩java成绩大于98分_1028学习

    1028学习 1028学习 day05 包的基本使用 java包的基本使用_pyhui的技术博客-CSDN博客 https://blog.csdn.net/ifubing/article/detail ...

  6. 软考中级(软件设计师)——面向对象程序设计(C++Java二选一的题15分-目标3分)

    软考中级(软件设计师)--面向对象程序设计(C++&Java二选一的题15分-目标3分) 目录 软考中级(软件设计师)--面向对象程序设计(C++&Java二选一的题15分-目标3分) ...

  7. java的三大体系分别是什么

    java的三大体系分别是什么? java的三大体系分别是JavaEE.JavaSE.JavaME.这使软件开发人员.服务提供商和设备生产商可以针对特定的市场进行开发. Java SE(Java Pla ...

  8. java计算时针和分针的夹角_【Java算法】一天24小时中,时针和分针一共重合多少次?...

    思路:利用时针与分针的夹角来计算.参考:上一篇文章 因为电子钟表,表针的跳动不是连续的,譬如分钟每次跳动6度,时针每次跳动0.5度.而编写程序时变量h小时,m分钟每次增量为1,所以我们设夹角gap为( ...

  9. Java实现求解硬币问题有1分、2分、5分、10分、50分和100分的硬币各若干枚,现在要用这些硬币支付W元,最少需要多少枚硬币?利用贪心法的思想进行编程

    求解硬币问题.有1分.2分.5分.10分.50分和100分的硬币各若干枚,现在要用这些硬币支付W元,最少需要多少枚硬币? 1.我解决该问题编程的思路如下: 首先是利用一个数组A存储硬币面额,再利用另外 ...

最新文章

  1. jetson nano包安装
  2. Eclipse(javaweb)刚换工作空间之后,应该做哪几件事
  3. Python爬虫基本库的使用
  4. 前后对接数字几_开源数字货币交易所开发学习笔记(1)——系统架构
  5. python3写的一个检测远程服务器端口脚本
  6. 详解Python使用模拟退火算法求解列表“最大值”
  7. linux驱动基础开发2——linux 驱动开发前奏(模块编程)-转
  8. Docker docker-compose 配置lnmp开发环境
  9. 怎么把java安装到64位_怎么安装64位JAVA,大师来详解
  10. tomcat 8.0下载
  11. python实战项目词云生成器(wordcloud+jieba+pyinstaller打包)——词云生成软件【Pyinstaller打包问题解决】
  12. 不同域名间的session共享
  13. Sam Altman 山姆奥特曼:如何成功 ?How To Be Successful
  14. java判断字符串长度_java判断中文字符串长度的简单实例
  15. android studio模拟手机黑屏,Android Studio 模拟器启动问题——黑屏 死机 解决方法...
  16. 2017年朋友圈最爆笑新闻,哈哈哈哈哈哈哈哈哈
  17. 腾讯发布的开发语言安全指南:C/C++安全指南
  18. 中芯微761的随身WiFi怎么切卡去除后门
  19. ArcGIS API for JS 4.x + Vue 【1】—— 显示地图和添加点线面
  20. axure9 汉化之后打不开

热门文章

  1. 皮一皮:千万别得罪一个文科生...
  2. 就在昨天,又一次上亿级的架构事故发生了!
  3. 2020 年 5 大 DevOps 趋势
  4. android gridview不显示 自定义,Android gridview和自定义标题
  5. 将矩阵转为一行_矩阵与矩阵乘积简介
  6. 帝国Cms百度小程序自然搜索之资源删除功能的使用
  7. c++ vector嵌套传参
  8. android-ndk-r15c libncurses.so.5
  9. Ubuntu 16.04 安装 miniconda
  10. setting an array element with a sequence