题解 Bessie's Interview
问题背景
Bessie 是一头牛,她在 K 名农夫进行面试后才到达。已知 N 头牛在她之前已经进行了面试,每个牛的面试时间不同,Bessie 定义为第 N+1 头牛。每位农夫面试一头牛需一定时间,只要有农夫空闲就会继续面试下一个牛。任务是计算 Bessie 的面试开始时间,以及哪些农夫可能会面试她。
做题思路
-
优先队列初始化:
- 使用优先队列
q
存储农夫面试的时间和农夫的编号,确保可以快速获取哪个农夫在何时完成面试。
- 使用优先队列
-
时间推进:
- 程序开始时,前 K 头牛和 K 名农夫进行面试被压入队列。
- 通过一个循环,不断推进时间,直到 Bessie 的面试时刻被确定:
- 从优先队列中获取将要完成面试的最早农夫,并记录对应的牛的编号。
- 若多个农夫同时完成面试,记录这些农夫的编号以便后续使用。
-
Bessie 的面试开始时间:
- 当所有之前的牛面试完后, Bessie 开始面试。面试开始的时间即为优先队列中最早的时间。
-
记录可能面试的农夫:
- 使用一个图结构
g
来追踪哪些农夫曾与哪些牛面试过。 - 使用一个访问数组
vis
来标记哪些农夫可能会面试 Bessie。 - 若一个农夫最后面试了 Bessie,则记录该农夫。
- 使用一个图结构
-
输出结果:
- 输出 Bessie 的面试开始时间。
- 输出一个 K 长的数组,记录每个农夫是否可能面试 Bessie(1 表示可能,0 表示不可能)。
代码示例
#include<bits/stdc++.h>
using namespace std;
int n,k,t[300005],now,id[300005],top,cnt,pos;
long long tmp;
bool vis[3000005];
priority_queue < pair <long long,int>,vector < pair <long long,int> >,greater < pair <long long,int> > > q;
queue <int> q2;
vector <int> g[3000005];
int main(){
freopen("interview.in","r",stdin);
freopen("interview.out","w",stdout);
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>k;
for(int i = 1;i <= n;i++){
cin>>t[i];
}
for(int i = 1;i <= k;i++){
q.push(make_pair(t[i],i));
}
now = cnt = k;
while(now < n){
tmp = q.top().first;
top = 0;
while(q.size() && q.top().first == tmp){
id[++top] = q.top().second;
q.pop();
}
pos = ++cnt;
for(int i = 1;i <= top;i++){
g[pos].push_back(id[i]);
g[++cnt].push_back(pos);
if(now + i <= n){
q.push(make_pair(tmp + t[now + i],cnt));
}
else{
q.push(make_pair(tmp,cnt));
}
}
now += top;
}
tmp = q.top().first;
cout<<tmp;
while(q.size() && q.top().first == tmp){
vis[q.top().second] = true;
q2.push(q.top().second);
q.pop();
}
while(q2.size()){
tmp = q2.front();
q2.pop();
for(int i = 0;i < g[tmp].size();i++){
if(!vis[g[tmp][i]]){
vis[g[tmp][i]] = true;
q2.push(g[tmp][i]);
}
}
}
for(int i = 1;i <= k;i++){
cout<<vis[i];
}
return 0;
}