题解 Bessie's Interview

问题背景

Bessie 是一头牛,她在 K 名农夫进行面试后才到达。已知 N 头牛在她之前已经进行了面试,每个牛的面试时间不同,Bessie 定义为第 N+1 头牛。每位农夫面试一头牛需一定时间,只要有农夫空闲就会继续面试下一个牛。任务是计算 Bessie 的面试开始时间,以及哪些农夫可能会面试她。

做题思路

  1. 优先队列初始化:

    • 使用优先队列 q 存储农夫面试的时间和农夫的编号,确保可以快速获取哪个农夫在何时完成面试。
  2. 时间推进:

    • 程序开始时,前 K 头牛和 K 名农夫进行面试被压入队列。
    • 通过一个循环,不断推进时间,直到 Bessie 的面试时刻被确定:
      • 从优先队列中获取将要完成面试的最早农夫,并记录对应的牛的编号。
      • 若多个农夫同时完成面试,记录这些农夫的编号以便后续使用。
  3. Bessie 的面试开始时间:

    • 当所有之前的牛面试完后, Bessie 开始面试。面试开始的时间即为优先队列中最早的时间。
  4. 记录可能面试的农夫:

    • 使用一个图结构 g 来追踪哪些农夫曾与哪些牛面试过。
    • 使用一个访问数组 vis 来标记哪些农夫可能会面试 Bessie。
    • 若一个农夫最后面试了 Bessie,则记录该农夫。
  5. 输出结果:

    • 输出 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;
}
posted @ 2024-10-23 11:00  健康铀  阅读(6)  评论(0编辑  收藏  举报