银行排队问题
其实就按照平常你排队的思路来解题就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;
}