[CCPC 2024 Shandong I] 打印机题解

题目描述

SUA 程序设计竞赛命题组的裁判们正在为即将举行的 2024 中国大学生程序设计竞赛全国邀请赛(山东)暨 CCPC 山东省大学生程序设计竞赛打印试题。

文印店里共有 n 台打印机。第 i 台打印机每 ti​ 秒可以打印一份试题。然而,第 i 台打印机每次打印出 li​ 份试题后,必须停机 wi​ 秒防止过热。也就是说,第 i 台打印机将重复进行以下工作计划:持续工作 ti​×li​ 秒,然后停机 wi​ 秒。

裁判们将同时使用所有打印机。求打印 k 份试题至少需要多少秒。

输入格式

有多组测试数据。第一行输入一个整数 T(1≤T≤100)表示测试数据组数,对于每组测试数据:

第一行输入两个整数 n 和 k(1≤n≤100,1≤k≤109)表示打印机的数量和需要的试题数量。

对于接下来的 n 行,第 i 行输入三个整数 ti​,li​ 和 wi​(1≤ti​,li​,wi​≤109)。它们的意义如上所述。

输出格式

每组数据输出一行一个整数,表示打印试题至少需要多少秒。

输入输出样例

输入 #1复制

2
3 15
3 4 5
5 7 2
1 2 20
1 100
1 1 100

输出 #1复制

25
10000

说明/提示

对于第一组样例数据,在 25 秒内,第一台打印机可以打印 6 份试题,第二台打印机可以打印 5 份试题,第三台打印机可以打印 4 份试题。所以一共打印了 6+5+4=15 份试题。

思路

二分查找即可,需要用__int128。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long t,n,k;
struct one{
    long long t,l,w;
}a[105];
void write(__int128 x){
    if(x>9){
        write(x/10);
    }
    putchar(x%10+'0');
    return;
}
bool abc(__int128 a1){
    __int128 lk=0,kl=0,ls=0;
    for(int i=1;i<=n;i++){
        kl+=(__int128)(a1/(__int128)((__int128)a[i].t*a[i].l+a[i].w))*a[i].l;
        ls=(__int128)(a1/(__int128)((__int128)a[i].t*a[i].l+a[i].w))*((__int128)a[i].t*a[i].l+a[i].w);
        if(a1-ls>=(__int128)a[i].t*a[i].l){
            kl+=a[i].l;
        }
        else{
            kl+=(__int128)(a1-ls)/a[i].t;
        }
    }
    if(kl>=(__int128)k){
        return 1;
    }
    else{
        return 0;
    }
}
int main(){
    cin>>t;
    while(t--){
        cin>>n>>k;
        for(int i=1;i<=n;i++){
            cin>>a[i].t>>a[i].l>>a[i].w;
        }
        __int128 l=0,r=1e18,md=1e18;
        r*=r;
        md*=md;
        while(l<=r){
            __int128 mid=(l+r)/2;
            if(abc(mid)==1){
                if(mid<md){
                    md=mid;
                }
                r=mid-1;
            }
            else{
                l=mid+1;
            }
        }
        write(md);
        cout<<endl;
    }
    return 0;
}

posted @ 2025-10-17 20:02  bz02_2023f2  阅读(14)  评论(0)    收藏  举报  来源