大体题意:
告诉你工作站的工作起始时间 终止时间, 和处理一个人的时间间隔。
并告诉你n 个人来的时间。 求你要求的话 什么时候去 排队时间最少, 如果你和某个人去的时间一样,你会排在它们后面。
思路:
暴力贪心就好了。
先找有缝的,发现一个人的就诊时间大于上一个人结束时间,那么直接输出 上一个人输出时间。
以上找的是不用排队的时间。
如果找不到,就要找需要排队的时间。
直接枚举每个人来的时间,看看在这个人前面行不行,更新最小排队时间即可。
#include <bits/stdc++.h>
#define mr make_pair
#define ps push_back
#define fi first
#define se second
#define Siz(x) (int)x.size()
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const int maxn = 100000 + 10;
int n;
LL s,t,k,st[maxn],ed[maxn];
LL a[maxn];
int main(){
scanf("%lld %lld %lld",&s, &t, &k);
scanf("%d",&n);
if (n == 0) return 0 * printf("%lld\n",s); ///= = 好坑啊,n 能等于0
for (int i = 0; i < n; ++i){
scanf("%lld",a+i); ///每个人来的时间
}
if (a[0] > s){
return 0 * printf("%lld\n",s);
}
memset(st,inf,sizeof st);
memset(ed,inf,sizeof ed);
LL la = -1;
LL ans = -1;
la = s+k;
st[0] = s; ///每个人的开始就诊时间
ed[0] = s+k;/// 每个人结束就诊时间。
for (int i = 1; i < n; ++i){
// printf("la = %lld",la);
if (la >= t) break;
if (a[i] > la){
if (la+k<=t) return 0 * printf("%lld\n",la);
la = a[i]+k;
st[i] = a[i];
ed[i] = a[i]+k;
continue;
}
if (la+k > t)break;
st[i] = la;
ed[i] = la+k;
la += k;
}
if (la < t && la+k<=t) return 0 * printf("%lld\n",la);
///=====================
///以下找需要排队的时间
ans = 1e18;
LL pos = 0;
for (int i = 0; i < n; ++i){
if (st[i] == inf || ed[i] == inf)break;
if (i == 0){
if (a[0] - 1 >= 0){
if (ans > st[0] - (a[0]-1) ){
ans = st[0] - (a[0]-1);
pos = a[0] - 1;
}
}
}
else {
if (ans > st[i] - (a[i]-1)){
ans = st[i] - (a[i] - 1);
pos = a[i]-1;
}
}
}
printf("%lld\n",pos);
return 0;
}
/**
7 14 3
2
1 2
30 60 3
10
1 5 6 10 12 13 18 23 24 25
**/