P9556 [SDCPC2023] A-Orders 题解

2023/08/18 Blog

签到题,是这场比赛第二简单的题。

解法

考虑要在第 $a_i$ 天交付 $b_i$ 件货物,我们就将订单按照 $a_i$ 排序。在每件订单之前(包括这个订单)工厂最多可以生产 $a_i \times k$ 件货物,如果 $\sum \limits _{i=1} ^{i \le a_i} b_i > a_i \times k$,则一定不能按时交付。否则如果一直满足 $\sum \limits _{i=1} ^{i \le a_i} b_i \le a_i \times k$,则有解。

实现方案一

排完序后对 $b_i$ 求一遍前缀和,记作 $pre_i$,每求完一次前缀和就判断一下是否满足 $pre_i \le a_i \times k$,如果不满足则无解,如果一直满足则有解。

实现方案二

排完序后遍历从 $1$ 到 $n$ 的订单,对于每次订单,我们可以记录一下交付完这次订单最多有多少剩余货物,定义为 $last_i$,$last_i = (a_i - a_{i-1}) \times k + last_i - b_i$($i \ge 2$),我们认为 $last_1 = a_1 \times k - b_1$。如果 $\exists i \in [1,n]$ 使得 $last_i < 0$,则无解,否则有解。

代码(实现方案二)

#include<bits/stdc++.h>
using namespace std;
namespace fast_IO
{
    /*
    快读快写代码,可忽略。
    */
};
using namespace fast_IO;
#define int long long
int t,n,k,last,flag;
struct node
{
    int a,b;
};
node arr[200];
inline bool cmp(const node &x,const node &y)
{
    return x.a<y.a;
}
signed main()
{
    read(t);
    while(t--)
    {
        read(n),read(k),last=0,flag=0;
        for(int i=1;i<=n;i++) read(arr[i].a),read(arr[i].b);
        sort(arr+1,arr+1+n,cmp);
        if(arr[1].a*k<arr[1].b)
        {
            write("No\n");
            continue;
        }
        last=arr[1].a*k-arr[1].b;
        for(int i=2;i<=n;i++)
        {
            if((arr[i].a-arr[i-1].a)*k+last<arr[i].b)
            {
                write("No\n"),flag=1;
                break;
            }
            last=(arr[i].a-arr[i-1].a)*k+last-arr[i].b;
        }
        if(!flag) write("Yes\n");
    }
    fwrite(Ouf,1,p3-Ouf,stdout),fflush(stdout);
    return 0;
}
对我博客最大的鼓励来自于你的评论(什么玩梗),欢迎选择 来回复, 也可以在 GitHub discussion 留言。

Search

    公告

    博主这下真摆烂了。我下辈子也不碰 Jekyll 和 MathJax 了!
    留言板,现在博主的精神状态非常好,有事烧纸。

    联系方式

    QQ: 33299235
    email: 33299235@qq.com
    Gmail: scp020.cn@gmail.com

    本人的其它个人主页

    洛谷
    CSDN

    友链

    拜谢stevehim(已退役,祝好)
    拜谢日记
    拜谢cppomstar

    views counting

    Document

    Table of Contents