P10098 [ROIR 2023] 地铁建设 (Day 2)

题目背景

翻译自 ROIR 2023 D2T1

用于铺设地铁隧道的盾构机有 n 个发动机。所有发动机是并联的,所以所有发动机两端的电压都相同。

每个发动机有两种模式,假设所有发动机接收到的电压都为 x,则当 x≤zi​ 时第 i 个发动机在第一模式下工作,否则它在第二模式下工作。

第 i 个发动机在第一模式下的单位电流为 ai​,在第二模式下的单位电流为 bi​。所以,根据 P=UI,当发动机处于第一模式时,每增加 1 单位电压,其功率增加 ai​ 单位;当发动机处于第二模式时,每增加 1 单位电压,其功率增加 bi​ 单位。换句话说,当电压为 x 单位电压,如果第 i 个发动机处于第一模式下,它以 ai​×x 的单位功率运行;如果处于第二模式下,它以 ai​×zi​+bi​×(x−zi​) 的单位功率运行。

题目描述

最少需要提供多大的电压(电压需要是整数),才能使所有发动机的总功率大于或等于 p?

输入格式

第一行输入两个整数 n 和 p。

接下来的 n 行,每行包含三个整数 zi​,ai​,bi​。

输出格式

输出一个整数表示最小电压。

输入输出样例

输入 #1复制

1 6
4 1 2

输出 #1复制

5

输入 #2复制

3 15
2 3 3
4 2 1
5 2 2

输出 #2复制

3

说明/提示

本题使用捆绑测试。

子任务编号分值特殊性质
120n=1
220ai​,bi​≤100,p≤105
320所有 zi​ 均相等
420n≤2
520

对于 100% 的数据,1≤n≤100,1≤p≤10^12,1≤zi​≤10^9,1≤ai​,bi​≤10^4。

分析:

这是一个明显的二分答案的题,x也就是电压越大,功率越强,所以电压越大,就越容易达到目标,所以成功区,也就是达到目标的区域在右边,题目所求的就是成功区最左侧的端点。

代码和注释:

#include<bits/stdc++.h>
using namespace std;

long long n, p;
long long a[105], z[105], b[105];

// 检查电压为 x 时总功率是否 >= p
bool check(long long x) {
    long long sum = 0;
    for (long long i = 0; i < n; i++) {
        if (x > z[i]) {
            // 第二模式
            sum += a[i] * z[i];               // 第一阶段的功率
            sum += (x - z[i]) * b[i];         // 第二阶段的功率
        } else {
            // 第一模式
            sum += a[i] * x;
        }
    }
    return sum >= p;
}

// 二分查找最小满足条件的电压
long long search() {
    long long l = -1, r = p + 1;  // 初始范围 [0, p+1]
    while (l + 1 < r) {
        long long mid = (l + 1 + r) >> 1;  // 等价于 (l + r + 1)/2
        if (check(mid)) {
            r = mid;  // 可行,尝试更小的电压
        } else {
            l = mid;  // 不可行,必须增大电压
        }
    }
    cout << r;       // 输出最小可行电压
    return 0;
}

int main() {
    cin >> n >> p;
    for (long long i = 0; i < n; i++) {
        cin >> z[i] >> a[i] >> b[i];
    }
    search();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值