pat1017

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);
    
    }
}



你可能感兴趣的:(模拟)