pat里面有好几题都是模拟这种排队的,包括1014还有1030等,个人觉得这样的题目挺不错,可以考验你的模拟能力。
就1017来说,要注意一点:17点一定关门,只要是17点前来的都要服务,即使可能超时 ,主要思想是:枚举每一个来的客户,当他们到达时,枚举每个窗口看是不是有窗口可以给他服务,如果有则服务,修改给与服务窗口的下次可服务时间,如果所有窗口都不能给他服务,那么客户就找一个等待时间最小的窗口,等候该时间的到达,然后进行服务修改等。
代码如下:
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int f(int a,int b,int c)
{
return a*3600+b*60+c;
}
struct node
{
int cos;
int st;
}p[10001];
bool cmp(node a,node b)
{
return a.st<b.st;
}
int main()
{
int n,m;
int win[101];
while(scanf("%d%d",&n,&m)!=EOF)
{
int cnt=0;
int ans=0;
int i,j;
for(i=1;i<=n;i++)
{
int a,b,c,x;
scanf("%d:%d:%d",&a,&b,&c);
scanf("%d",&x);
if(f(a,b,c)<17*3600)
{
p[++cnt].st=f(a,b,c);
p[cnt].cos=x;
}
}
sort(p+1,p+cnt+1,cmp);
for(i=1;i<=cnt;i++)
{
if(p[i].st<8*3600)
{
ans+=(8*3600-p[i].st);
p[i].st=8*3600;
}
}
for(i=1;i<=m;i++)
win[i]=8*3600;
for(i=1;i<=cnt;)
{
int find=0;
int dd;
for(j=1;j<=m;j++)
if(win[j]<=p[i].st)
{
find=1;
dd=j;
break;
}
if(find==1)
{
win[dd]=p[i].st+p[i].cos*60;
i++;
}
else
{
int min=1<<30;
for(j=1;j<=m;j++)
if(min>win[j])
min=win[j];
ans+=(min-p[i].st);
p[i].st=min;
}
}
if(cnt==0)
printf("0.0\n");
else
printf("%.1lf\n",1.0*ans/cnt/60);
}
}