欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PAT 甲级 1014 Waiting in Line【queue】

程序员文章站 2024-03-18 11:38:16
...

排队场景,用队列实现即可。

具体思路:前n*m个人直接按顺序安排上,并不需要把人安排到先办完业务的人后头,只需要看队伍人数就行(一开始就错在这里3和4样例过不去)。然后黄线后面的人,从黄线内的队伍找,出去一个进来一个就行了。

坑点提示:如果某个人17:00前开始办业务就可以完成,以张三为例,张三16:00排上队开始办理业务,但是需要办1个小时10分钟,也就是17:10才完成,这种情况也算完成,但是排在张三后面的李四就不行了,他是17:10分才能开始办理业务,这时候已经下班了。

代码:

//1014 queue

//窗口
queue<int> window[21];
//窗口当前队完成时的分钟数
int win_min[21];

//所有顾客需要的业务时间,注意从1开始
//记录所有顾客将要完成的时间
int per[1005],serve[1005];

int n,m,k,q,query;

int window_out(){
    //找到最先空出位置的队列
    int free_p=1,min_n = serve[window[1].front()];

    for(int i=n;i>0;i--){
        //min_n的意思是当前窗口的队头的人处理完业务的时间
        if(min_n >= serve[window[i].front()]){
            min_n = serve[window[i].front()];
            free_p = i;
        }
    }

    window[free_p].pop();

    return free_p;
}

void process(){

    int i,minn,free_poi;
    for(i=1;i<=k;i++){
        //前面n*m个直接顺序安排上就行
        if(i<=n*m){
            window[i%n+1].push(i);
            if(win_min[i%n+1]>=540) serve[i] = -1;
            else serve[i] = win_min[i%n+1] + per[i];
            win_min[i%n+1] += per[i];
        }
        else{
            free_poi = window_out();
            window[free_poi].push(i);
            if(win_min[free_poi]>=540) serve[i] = -1;
            else serve[i] = win_min[free_poi] + per[i];
            win_min[free_poi] += per[i];

        }

    }

    return ;
}


int main(){
    scanf("%d %d %d %d",&n,&m,&k,&q);

    for(int i=1;i<=k;i++) scanf("%d",per+i);

    process();

    while(q--){
        scanf("%d",&query);
        //printf("%d\n",serve[query]);
        int t = serve[query];
        if(t<0) printf("Sorry\n");
        else printf("%02d:%02d\n",(t/60)+8,t%60);
    }

    return 0;
}