PAT Advanced 1014. Waiting in Line in C.

银行排队问题

其实就按照平常你排队的思路来解题就OK的,不过有几个坑,可能也不能叫做坑,对思维缜密的人来讲就应该不是坑,既然你看到了我的这篇,很有可能你的思维可能跟我一样还不够缜密。


思路如下:
首先将所有的顾客看成两部分,一个是窗口前,正在处理事务的人,一个是在后面等候处理的人(包括黄线外);
对一个顾客来讲,从他进门,他的心路历程应该是这样的:
1:如果黄线内的窗口前面的队没有排满的话,他从第一个窗口看过去,找个第一个最短的队(处理机制1)去排队(处理机制1);
2:如果队都排满了的话,就要等一个处理完(处理机制3)出来,然后去该处理完的顾客所在的队(处理机制3),然后去排队(处理机制1)。
“处理机制”如下:
1:查找黄线内最短的队列(最小值的查找);
2:顾客进黄线排队(入队);
3:查找窗口前需要时间最短的顾客(最小值的查找);
4:处理窗口前面第一位顾客(出队);
5:更新窗口前第一位顾客的剩余处理时间;
流程如下:
处理第 i 个顾客->如果黄线内没占满,顾客 i 进黄线->如果黄线内站满了,等待一个客户处理完出来,进入该窗口排队->继续处理第 i+1 个顾客……
如果黄线后无顾客了,则处理机制3->处理机制4循环直至窗口前所有顾客处理完。

每个顾客的完成时间处理:
在处理机制3之后,将所有窗口前第一位顾客的处理时间都减去最短的处理时间,然后当前时间加上最短的处理时间;如果第一位顾客的剩余处理时间为0,则说明该顾客处理完毕,当前时间就是该顾客的完成时间。


说的好像很乱,欢迎来交流^_^


AC Code:

#include <stdio.h>
#include <stdlib.h>
#define max_customer_num 1001
#define max_window_num 21 
#define max_queue_capacity 11
#define max_time 1440 //maximum processting time of customers
#define close_time 540
typedef struct customer
{
    int id; /*customer id: 0~k*/
    struct customer *next;
} customerNode;
typedef struct window
{
    /*the queue node in front each window*/
    int num;
    struct customer *front;
    struct customer *rear;
} windowNode;
void create_window_queue(windowNode *wq)
{
    wq->front=wq->rear=(customerNode *)malloc(sizeof(customerNode));
    wq->front->next=NULL;
    wq->num=0;
}
void en_window_queue(int x,windowNode *wq)
{
    /*customer x waiting in front of window wq*/
    customerNode *customer=(customerNode *)malloc(sizeof(customerNode));
    customer->id=x;
    customer->next=NULL;
    wq->rear->next=customer;
    wq->rear=customer;
    wq->num++;
}
int de_window_queue(windowNode *wq)
{
    int x;
    customerNode *customer=wq->front->next;
    wq->front->next=customer->next;
    x=customer->id;
    wq->num--;
    if(wq->num==0) wq->rear=wq->front;
    free(customer);
    return x;
}
int get_first(windowNode wq)
{
    int x=wq.front->next->id;
    return x;
}
void format_time_output(int a)
{
    /*print time in hh:mm format*/
    int h,m;
    if(a==-1) printf("Sorry\n");
    else
    {
        m=a%60;
        h=a/60+8;
        printf("%02d:%02d\n",h,m);
    }
}
int main()
{
    int n,m,k,q; /*number of windows, capacity of each window, customers and queries*/
    int i,j,cus_inside,min_cus_waiting_num,min_win,min_proc_time,first,quickest_window; /*tempary variables*/
    int current_time;
    int process_time[max_customer_num],time_left[max_customer_num],query[max_customer_num],finish_time[max_customer_num]={0};
    windowNode window[max_window_num];
    /*scan info*/
    scanf("%d %d %d %d",&n,&m,&k,&q);
    for(i=0;i<k;i++)
    {
        scanf("%d",&process_time[i]);
        time_left[i]=process_time[i];
    }
    for(i=0;i<q;i++)
    {
        scanf("%d",&query[i]);
    }
    for(i=0;i<n;i++)
    {
        window[i].front=window[i].rear=(customerNode *)malloc(sizeof(customerNode));
        window[i].front->next=NULL;
        window[i].num=0;
    }

    /*star queuing and processing*/
    current_time=0; /*initiate current time relative to 8:00*/
    cus_inside=0; /*number of customer inside the yellow line*/
    for(i=0;i<k;i++)
    {
        /*put all customer in the yellow line*/
        if(cus_inside<n*m)
        {
            /*customer i can go inside the yellow line*/
            /*then find the window with fewest customers waiting*/
            min_cus_waiting_num=m;
            for(j=0;j<n;j++)
            {
                if(window[j].num<min_cus_waiting_num)
                {
                    min_cus_waiting_num=window[j].num;
                    min_win=j;
                }
            }
            /*customer i enqueue*/
            en_window_queue(i,&window[min_win]);
            cus_inside++;
        }
        else
        {
            /*find the customer with shortest processing time*/
            min_proc_time=max_time;
            for(j=0;j<n;j++)
            {
                first=get_first(window[j]);
                if(time_left[first]<min_proc_time)
                {
                    min_proc_time=time_left[first];
                    quickest_window=j;
                }
            }
            /*update current time*/
            current_time+=min_proc_time;
            for(j=0;j<n;j++)
            {
                /*update in-processing-customers' left time*/
                first=get_first(window[j]);
                time_left[first]-=min_proc_time;
                if(time_left[first]==0)
                {
                    /*customer first processed*/
                    de_window_queue(&window[j]);
                    /*update its finish time*/
                    if(current_time-process_time[first]>=close_time)
                    {
                        /*customer first start being processed after the bank's closed*/
                        /*this process can be omited*/
                        finish_time[first]=-1;
                    }
                    else
                    {
                        /*customer first start being processed before the bank's closed*/
                        /*this process can't be omited no matter how long it takes*/
                        finish_time[first]=current_time;
                    }
                    cus_inside--;
                }
            }
            en_window_queue(i,&window[quickest_window]);
            cus_inside++;
        }
    }
    while(cus_inside>0)
    {
        /*same as the 'else' part above*/
        min_proc_time=max_time;
        for(j=0;j<n;j++)
        {
            if(window[j].num>0){
                first=get_first(window[j]);
                if(time_left[first]<min_proc_time)
                {
                    min_proc_time=time_left[first];
                    quickest_window=j;
                }
            }
        }
        current_time+=min_proc_time;
        for(j=0;j<n;j++)
        {
            if(window[j].num>0){
                first=get_first(window[j]);
                time_left[first]-=min_proc_time;
                if(time_left[first]==0)
                {
                    de_window_queue(&window[j]);
                    if(current_time-process_time[first]>=close_time) finish_time[first]=-1;
                    else finish_time[first]=current_time;
                    cus_inside--;
                }
            }
        }
    }
    /*start query*/
    for(i=0;i<q;i++)
    {
        format_time_output(finish_time[query[i]-1]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值