题目
假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙。当有窗口空闲时,下一位顾客即去该窗口处理事务。当有多个窗口可选择时,假设顾客总是选择编号最小的窗口。
本题要求输出前来等待服务的N位顾客的平均等待时间、最长等待时间、最后完成时间,并且统计每个窗口服务了多少名顾客。
思路
具体实现思路,模仿了操作系统中的进程调度占用cpu的状态分析。注意完成时间,最后完成时间,一定是最后window数组中最长的那个。
代码
#include<stdio.h>
#include<stdlib.h>
#define N 1000
#define M 10
typedef struct consumer{
int beganTime;
int workTime;
}consumer;
int findMin(int x);
void sort(int low,int high);
int Quick(int low,int high);
consumer con[N];
int n,k,window[M],wait[N],windowCount[M];//window存储完成时间,wait存储等待时间,windowCount存储每个窗口的访问次数
void main(){
int i,j,index;
float sum=0.0;
int maxW=0,Mtime=0;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d %d",&con[i].beganTime,&con[i].workTime);
if(con[i].workTime>60)
con[i].workTime=60;
}
sort(0,n-1);//按先来后到顺序排序
scanf("%d",&k);
for(i=0;i<k;i++)//初始化window
window[i]=0;
for(i=0;i<n;i++)//初始化wait
wait[i]=0;
for(i=0;i<k;i++)
windowCount[i]=0;
for(i=0;i<n;i++){//核心
index=findMin(i);
windowCount[index]++;
printf("index=%d\n",index);
if(window[index]<=con[i].beganTime){
window[index]=con[i].beganTime+con[i].workTime;
}
else{
wait[i]=window[index]-con[i].beganTime;
window[index]=window[index]+con[i].workTime;
}
}
for(i=0;i<n;i++)
if(wait[i]){
sum+=wait[i];
if(maxW<wait[i])
maxW=wait[i];
}
printf("AvgWait=%.1f WaitMax=%d ",sum/n,maxW);
for(i=0;i<k;i++)
if(Mtime<window[i])
Mtime=window[i];
printf("Mtime=%d\n",Mtime);
for(i=0;i<k;i++)
printf(" %d",windowCount[i]);
system("pause");
}
int findMin(int x){
int i,index;
int min=65534;
for(i=0;i<k;i++){
if(con[x].beganTime>=window[i])//此处先判断一下,是否有窗口可用,依据题目总是寻找最小编号的窗口先使用
return i;
else if(min>window[i]){
min=window[i];
index=i;
}
}
if(min!=65534){
return index;
}else
return -1;
}
void sort(int low,int high){
int piv;
if(low<high){
piv=Quick(low,high);
sort(low,piv-1);
sort(piv+1,high);
}
}
int Quick(int low,int high){
consumer temp;
temp=con[low];
while(low < high){
while(low<high && temp.beganTime<=con[high].beganTime)
high--;
con[low]=con[high];
while(low<high && temp.beganTime>=con[low].beganTime)
low++;
con[high]=con[low];
}
con[low]=temp;
return low;
}
总结
需要注意的是findMin函数中注释部分,缺少此步就容易出现最后窗口次数访问不符合答案的情况。