1.题目
下课了,有 n 位同学陆续赶到食堂进行排队打饭,其中第 i 位同学的到达时间为 ai,打饭耗时为 ti,等待时间上限为 bi,即如果其在第 ai+bi
秒的时刻仍然没有轮到他开始打饭,那么他将离开打饭队列另寻吃饭的地方。
问每位同学的开始打饭时间,或者指出其提前离开了队伍(如果这样则输出 -1)。
输入格式
第⼀行一个整数 n (1<=n<=10^5),表示来打饭的同学数量。
接下来 n 行,每行三个整数 ai,ti,bi (1<=ai,ti,bi<=10^9, 1<=i<=n),分别表示每位同学的到达时间、打饭耗时、等待时间上限。
保证 a1<a2<…<an。
输出格式
⼀行n 个整数,表示每位同学的开始打饭时间或者 -1(如果该同学提前离开了队伍)。
样例输入
4
1 3 3
2 2 2
3 9 1
4 3 2
样例输出
1 4 -1 6
2.法一:
a[]打饭时间、b[]打饭耗时、ci排队呆最久的时间。
如给的测试用例:
4
1 3 3
2 2 2
3 9 1
4 3 2
即将c[i]改成排队能呆的最久的时间。
4
1 3 4
2 2 4
3 9 4
4 3 6
本题的每个人到达时间均是按序递增,直接模拟:
第一个人在t=1时到来,time
为1,打印第一个同学开始打饭的时间为t=max=1
,将time更新为max+b[i]=1+3=4;
第二个人在t=2时到来,time
为4,4>4不成立,打印第二个同学开始打饭的时间为t=max(4,2)=4
,将time更新为4+b[2]=4+2=6。
第三个人在t=3时到来,time
为6,6>4=a[3],a[3]为第三个人到达的时刻,成立即打印-1
。
第四个人在t=4时到来,time
为6,6>6不成立,打印max=(6,6)=6
,将time更新为6+3=9.
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stdlib.h>
using namespace std;
const int maxn=1e5+100;//题目说了最多10的5次方个同学
int a[maxn],b[maxn],c[maxn];
int main(){
int n,time;
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i],&b[i],&c[i]);
//第i位同学的到达时间、打饭用时、排队等待时间
c[i]=a[i]+c[i];//离开上限的时间
}
time=a[1];
for(int i=1;i<=n;i++){
if(i!=1){
printf(" ");
}
if(time>c[i]){//超时不予等待
printf("-1");
}else{
printf("%d",max(time,a[i]));
time=max(time,a[i])+b[i];
}
}
printf("\n");
}
system("pause");
}
3.法二
第1个人先到达后即不用花费排队时间,直接花费打饭时间即可,也就确定打饭结束的时刻endtime。
第2个人来的时刻arrive[1]
与endtime
做减法,
(1)如果该差值大于该人的max_waittime
时间就溜,即将-1存入ans数组;
(2)如果小于等于该人的max_waittime
时间,当然是留下继续等到前一个人打完饭后就轮到该人打饭,并将该人的打饭时间存入ans数组,最后得到该人的endtime(endtime=endtime+打饭时间)。
可以画个时间轴:
for(int i=1;i<n;i++){
if(arr[i]>endtime[i-1]){//此时队列没人,可直接打饭
endtime[i]=arr[i]+datime[i];
ans.push_back(arr[i]);
}
else if(arr[i]+waittime[i]<endtime[i-1]){
ans.push_back(-1);
endtime[i]=endtime[i-1];//容易漏!!
}
else{//即(arr[i]+waittime[i])>=endtime[i-1]则继续等
endtime[i]=endtime[i-1]+datime[i];
ans.push_back(endtime[i-1]);//endtime[i-1]即第i个人的开始打饭时间
}
}
也可以直接设置一个队列,每次出队进行判断,更新current
的值。
//解题思路:利用队列实现
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
struct node{
long long a;
long long t;
long long b;
};
int main() {
int n;
cin >> n;
queue<node> q;
vector<int> v;
while (n--) { //把所有学生按照先后次序入队
node stu;
cin >> stu.a >> stu.t >> stu.b;
q.push(stu);
}
int current = 1;
while (!q.empty()) {
node temp = q.front();
q.pop();
int ans;
if (temp.a + temp.b >= current) { //如果未超过等待时间
if (current > temp.a){
ans = current;
current += temp.t;
} else {
ans = temp.a;
current = temp.a + temp.t;
}
} else { //如果超过等待时间
ans = -1;
}
v.push_back(ans);
}
for (int i = 0; i < v.size(); i++) {
if (i == 0) cout << v[i];
else cout << " " << v[i];
}
return 0;
}