P1672 [USACO05FEB] Feed Accounting S
题目描述
约翰想知道上一船饲料是什么时候运到的。在饲料运到之前,他的牛正好把仓库里原来的饲料全吃光了。他收到运来的 F 1 ( 1 ≤ F 1 ≤ 1 0 6 ) F1(1\le F1\le 10^6) F1(1≤F1≤106) 千克饲料。遗憾的是,他已经不记得这是哪一天的事情了。到第 D ( 1 ≤ D ≤ 2 × 1 0 3 ) D(1\le D\le 2\times 10^3) D(1≤D≤2×103) 天为止,仓库里还剩下 F 2 ( 1 ≤ F 2 ≤ F 1 ) F2(1\le F2\le F1) F2(1≤F2≤F1) 千克饲料。
约翰养了 C ( 1 ≤ C ≤ 100 ) C(1\le C\le 100) C(1≤C≤100) 头牛,每头牛每天都吃掉恰好 1 1 1 千克饲料。由于不同的原因,牛们从某一天开始在仓库吃饲料,又在某一天离开仓库,所以不同的两天可能会有差距很大的饲料消耗量。每头牛在来的那天和离开的那天都在仓库吃饲料。给出今天的日期 D D D,写一个程序,判断饲料最近一次运到是在什么时候。今天牛们已经吃过饲料了,并且饲料运到的那天牛们还没有吃过饲料。
如果最终的答案有多个可能,请输出最大的(即,最近的)那一个。
输入格式
第 1 1 1 行:四个整数 C C C, F 1 F1 F1, F 2 F2 F2, D D D,用空格隔开。
第 2 2 2 到 C + 1 C+1 C+1 行:每行是用空格隔开的两个数字,分别表示一头牛来仓库吃饲料的时间和离开的时间。
输出格式
一个正整数,即上一船饲料运到的时间。
输入输出样例 #1
输入 #1
3 14 4 10
1 9
5 8
8 12
输出 #1
6
说明/提示
样例解释
上一次运来了 14 14 14 千克饲料,现在饲料还剩下 4 4 4 千克。最近 10 10 10 天里,有 3 3 3 头牛来吃过饲料。
约翰在第 6 6 6 天收到 14 14 14 千克饲料,当天吃掉 2 2 2 千克,第 7 7 7 天吃掉 2 2 2 千克,第 8 8 8 天吃掉 3 3 3 千克,第 9 9 9 天吃掉 2 2 2 千克,第 10 10 10 天吃掉 1 1 1 千克,正好还剩 4 4 4 千克。
数据规模
1 ≤ F 2 ≤ F 1 ≤ 1 0 6 1\le F2\le F1\le 10^6 1≤F2≤F1≤106, 1 ≤ D ≤ 2 × 1 0 3 1\le D\le 2\times 10^3 1≤D≤2×103, 1 ≤ C ≤ 100 1\le C\le 100 1≤C≤100。
C++实现
#include<bits/stdc++.h>
using namespace std;
int c,f1,f2,d,ate[110],Left[110],ans;
bool check(int x){//检查此答案是否合法
int jl=0;
for(int i=1;i<=c;i++){
if(ate[i]<=x){
if(Left[i]>=x&&Left[i]<=d)
jl+=Left[i]-x+1;
else if(Left[i]>d)
jl+=d-x+1;
}
else{
if(ate[i]<=d){
if(Left[i]>=d)
jl+=d-ate[i]+1;
else
jl+=Left[i]-ate[i]+1;
}
}
}
return jl>=f1-f2;
}
int main()
{
ios::sync_with_stdio(NULL);//快读
cin.tie(NULL);
cout.tie(NULL);
cin>>c>>f1>>f2>>d;
for(int i=1;i<=c;i++)
cin>>ate[i]>>Left[i];//ate表示此牛来的日期,Left表示离开日期
int l=1,r=d,mid;
while(l<=r){//二分答案
mid=(l+r)/2;
if(check(mid)){//如果此答案满足,则记录下来
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
cout<<ans;
return 0;
}
后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容