P9556 [SDCPC2023] A-Orders 题解
签到题,是这场比赛第二简单的题。
解法
考虑要在第 a i a_i ai 天交付 b i b_i bi 件货物,我们就将订单按照 a i a_i ai 排序。在每件订单之前(包括这个订单)工厂最多可以生产 a i × k a_i \times k ai×k 件货物,如果 ∑ i = 1 i ≤ a i b i > a i × k \sum \limits _{i=1} ^{i \le a_i} b_i > a_i \times k i=1∑i≤aibi>ai×k,则一定不能按时交付。否则如果一直满足 ∑ i = 1 i ≤ a i b i ≤ a i × k \sum \limits _{i=1} ^{i \le a_i} b_i \le a_i \times k i=1∑i≤aibi≤ai×k,则有解。
实现方案一
排完序后对 b i b_i bi 求一遍前缀和,记作 p r e i pre_i prei,每求完一次前缀和就判断一下是否满足 p r e i ≤ a i × k pre_i \le a_i \times k prei≤ai×k,如果不满足则无解,如果一直满足则有解。
实现方案二
排完序后遍历从 1 1 1 到 n n n 的订单,对于每次订单,我们可以记录一下交付完这次订单最多有多少剩余货物,定义为 l a s t i last_i lasti, l a s t i = ( a i − a i − 1 ) × k + l a s t i − b i last_i = (a_i - a_{i-1}) \times k + last_i - b_i lasti=(ai−ai−1)×k+lasti−bi( i ≥ 2 i \ge 2 i≥2),我们认为 l a s t 1 = a 1 × k − b 1 last_1 = a_1 \times k - b_1 last1=a1×k−b1。如果 ∃ i ∈ [ 1 , n ] \exists i \in [1,n] ∃i∈[1,n] 使得 l a s t i < 0 last_i < 0 lasti<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;
}
本文是 P9556 [SDCPC2023] A - Orders 题解。该题是签到题,为比赛第二简单的题。给出两种解法,一是排序后对 bi 求前缀和并判断;二是排序后遍历订单,记录剩余货物量判断。还给出了实现方案二的代码。
5098

被折叠的 条评论
为什么被折叠?



