CF1539C Stable Groups 题解
题目大意
现在有 个学生,每个学生的水平为 ,允许你往其中添加 个任意水平的学生。现在要求你把这 个学生分成几组,使得每一组中的水平大小相邻的学生的水平绝对差小于等于 。
思路分析
考虑贪心
可以先对学生的水平排一下序,算绝对差,把绝对差存储到一个数组里,接着对这个绝对差数组做贪心。
如何贪心
因为绝对差小的情况更容易满足,所以我们要先对绝对差数组排序,使得绝对差小的情况先考虑,绝对差大的情况后考虑。
如果绝对差大于 ,可以用两种办法解决:
- 能用加学生解决的,就用加学生解决。(并且要使得加的学生尽量少)
- 不能用加学生解决的,可以直接分成两组,避免两个人在同一组内。
代码剖析
3.1:差分
sort(a+1,a+n+1);
for(int i=2;i<=n;i++){
b[i-1]=a[i]-a[i-1];
}
sort(b+1,b+n);
数组存储了两个水平相邻学生的绝对差,这里可以不带绝对值,因为 的结果是从小到大的。
最后对 数组排序,以便后面做贪心。
3.2:贪心
for(int i=1;i<n;i++){
if(b[i]>x){//如果需要操作
if(k>=(b[i]-1)/x){//看一看可不可以通过加学生解决
k-=(b[i]-1)/x;//可以就让可用学生减掉需要学生
}
else{
cnt++;//否则就分组,分组的次数加1。
}
}
}
首先判断这个差是否需要操作,如果不需要,就不管了。
如果需要,先尝试用加学生的办法去做。
- WARNING:这里减掉 是非常重要的。我们可以把学生看成隔板,把一段水平差分成几段,而段数比点数少 。
如果学生够用,把可用学生数量减去需要的学生数量。
否则就分一次组,让分组次数的计数器加 。
最后直接输出。
- WARNING:输出 !因为 记录的是分组的次数,分了 次,就会有 组。
AC Code
代码已分段给出,不给出完整代码
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现