专栏文章

题解:P14575 坤班

P14575题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@min25rvv
此快照首次捕获于
2025/12/01 19:20
3 个月前
此快照最后确认于
2025/12/01 19:20
3 个月前
查看原文
拿到题面先看一眼设问,看到最多,容易想到二分。我们考虑二分班级数量。
接下来考虑二分中的 check
  • s 数组记下每个科目分别可以教多少个班(就是把教某一科目的老师可以教的班的总和),方便后面算出空余的老师数量
  • 再统计一下每个科目老师里面可以当班主任的老师数量,这样就可以避免一下当不了班主任的老师当班主任了。
下面是 check 部分的代码
CPP
int s[200005], bzr[200005]; //bzr 记的是每个科目老师里面可以当班主任的老师数量
bool ck(int x)
{
    int cnt = 0; // 记的是所有科目里面分配出来可以当班主任的老师数量
    for (int i = 1; i <= m; i++)
    {
        cnt += min(s[i] - x, bzr[i]); //既要有空闲的老师,又要能当班主任
    }
    return cnt >= x; // 是否能每个班级都配备一个班主任
}
再来看看二分。
左边界毋庸置疑,肯定是 11。但是右边界的限制比较多了。
第一眼看到肯定是小于所有的班主任数量,但是这样只能拿 55 分。
另一个限制就是右边界必须小于 sis_i 中的任意值。
以上就是全部要点了,下面是代码,禁止抄袭

code

CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m;
int a[500005], b[500005], c[500005];
int s[500005], bzr[500005];
bool ck(int x)
{
    int cnt = 0;
    for (int i = 1; i <= m; i++)
    {
        cnt += min(s[i] - x, bzr[i]);
    }
    return cnt >= x;
}
signed main()
{
    cin >> n >> m;
    int cnt = 0;
    int mn = 1e9;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i] >> b[i] >> c[i];
        s[a[i]] += b[i];
        bzr[a[i]] += c[i];
        cnt += c[i];
    }
    for (int i = 1; i <= m; i++)
        mn = min(mn, s[i]);
    int l = 1, r = min(mn, cnt);
    while (l <= r)
    {
        int mid = (l + r) >> 1;
        if (ck(mid))
            l = mid + 1;
        else
            r = mid - 1;
    }
    cout << r << endl;
}
以上就是本篇题解的全部内容了。

评论

0 条评论,欢迎与作者交流。

正在加载评论...