PAT甲题题解-1017. Queueing at Bank (25)-模拟

有n个客户和k个窗口,给出n个客户的到达时间和需要的时长
有空闲的窗口就去办理,没有的话就需要等待,求客户的平均时长。
如果在8点前来的,就需要等到8点。
如果17点以后来的,则不会被服务,无需考虑。

按客户的到达时间排序
建立一个优先级队列,一开始放入k个窗口,初始结束时间为8*3600
然后for循环客户,每次从优先级队列中取出最早结束时间的窗口
如果客户比结束时间来的早,就需要等待
如果客户比结束时间来的晚,就无需等待
最后只要统计那些到达时间在17*3600之前的客户即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int maxn=10000;
int n,k;
struct Customer{
    int arrive; //到达时间
    int process; //服务时间
    int start;  //客户开始被服务的时间
    int finish; //客户的结束时间
    int wait; //客户的等待时间
    bool operator<(const Customer tmp)const{
        return arrive<tmp.arrive;
    }

}cus[maxn];
struct Window{
    int finish_time;
    bool operator<(const Window tmp)const{
        return finish_time>tmp.finish_time;
    }
};
int main()
{
    int h,m,s,t;
    scanf("%d %d",&n,&k);
    for(int i=0;i<n;i++){
        scanf("%d:%d:%d %d",&h,&m,&s,&t);
        cus[i].arrive=h*3600+m*60+s;
        if(t>60)
            t=60; //样例中其实也没有超过60分钟的数据,题目说了是假设
        cus[i].process=t*60;
    }
    priority_queue<Window>q;
    Window w;
    for(int i=0;i<k;i++){
        w.finish_time=8*3600;
        q.push(w);
    }
    sort(cus,cus+n);
    Window ww;
    for(int i=0;i<n;i++){
        w=q.top();
        q.pop();
        if(cus[i].arrive<w.finish_time){
            cus[i].wait=w.finish_time-cus[i].arrive;
            cus[i].start=w.finish_time;
            cus[i].finish=cus[i].start+cus[i].process;
            ww.finish_time=cus[i].finish;
            q.push(ww);
        }
        else{
            cus[i].start=cus[i].arrive;
            cus[i].wait=0;
            cus[i].finish=cus[i].start+cus[i].process;
            ww.finish_time=cus[i].finish;
            q.push(ww);
        }
    }
    double sum=0;
    int cnt=0;
    for(int i=0;i<n;i++){
        /*
        一开始和P1014搞混了,以为如果是17点之前还没被服务,就不考虑
        后来发现题目中明确说了,是17点之后到的才不考虑
        */
        if(cus[i].arrive<=17*3600){
            sum+=cus[i].wait;
            cnt++;
        }
    }
    if(cnt==0)
        printf("0.0\n"); //去掉这个也能AC,说明样例没有出现cnt为0的情况
    else{
        double minutes=sum/60.0/cnt;
        printf("%.1lf\n",minutes);
    }

    return 0;
}

时间: 2024-10-02 08:34:07

PAT甲题题解-1017. Queueing at Bank (25)-模拟的相关文章

PAT甲题题解-1036. Boys vs Girls (25)-找最大最小,大水题

题意:给出n个人的姓名.性别.ID.分数,让你找出其中哪个妹纸分数最高.哪个汉子分数最低.以及他们的差如果没有妹纸或者汉子,则对应输出Absent,差用NA代替. 就是for一遍找最大最小值,水题 #include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #include <cmath> #include <vector> #defin

PAT甲题题解-1012. The Best Rank (25)-排序水题

排序,水题因为最后如果一个学生最好的排名有一样的,输出的课程有个优先级A>C>M>E那么按这个优先级顺序进行排序每次排序前先求当前课程的排名然后再与目前最好的排名比较.更新 至于查询,建立id与索引的映射即可. #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <map> using namespace s

PAT甲题题解-1110. Complete Binary Tree (25)-(判断是否为完全二叉树)

题意:判断一个节点为n的二叉树是否为完全二叉树.Yes输出完全二叉树的最后一个节点,No输出根节点. 建树,然后分别将该树与节点树为n的二叉树相比较,统计对应的节点个数,如果为n,则为完全二叉树,否则即不是. #include <iostream> #include <cstdio> #include <algorithm> #include <string.h> using namespace std; const int maxn=22; int two

PAT甲题题解-1052. Linked List Sorting (25)-排序

三个注意点: 1.给出的n个节点并不一定都在链表中 2.最后一组样例首地址即为-1 3.输出地址的时候一直忘记前面要补0... #include <iostream> #include <algorithm> #include <cstdio> #include <string.h> using namespace std; const int maxn=100000+5; struct Node{ int addr; int val; int to; bo

PAT甲题题解-1014. Waiting in Line (30)-模拟,优先级队列

题意:n个窗口,每个窗口可以排m人.有k为顾客需要办理业务,给出了每个客户的办理业务时间.银行在8点开始服务,如果窗口都排满了,客户就得在黄线外等候.如果有一个窗口用户服务结束,黄线外的客户就进来一个.如果有多个可选,选窗口id最小的.输出查询客户的服务结束时间. 如果客户在17点(注意是包括的!!!就在这里被坑了,一开始还以为不包括...)或者以后还没开始服务,就输出Sorry如果已经开始了,无论多长都会继续服务的. 思路:建立一个优先级队列,存储在黄线之内的所有客户.对于m*n之前的人,依此

PAT甲题题解-1007. Maximum Subsequence Sum (25)-求最大子区间和

题意:给出n个数,求最大连续的子区间和,并且输出该区间的第一个和最后一个数. 如果所有数都小于0,那么则输出0,第一个数和最后一个数. 看数据k的范围,就知道肯定不能两层for循环来求区间和,O(n^2)的复杂度肯定超时所以这里肯定要求一遍for循环就能知道结果定义区间l和r,sum为目前[l,r]之间的和一开始l=r=0,sum=a[0]接下来,对于当前第i个数字a[i]如果sum+a[i]>a[i],那么就将a[i]一起加入到区间中去.如果sum+a[i]<a[i],那么还不如不加,直接重

PAT甲题题解-1009. Product of Polynomials (25)-多项式相乘

多项式相乘 注意相乘结果的多项式要开两倍的大小!!! #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string.h> using namespace std; //两个多项式相乘 const int maxn=1000+5; int k; //原本定义个exp导致编译错误,没想到定义成exp1.exp2也会编译错误,

PAT甲题题解-1013. Battle Over Cities (25)-求联通分支个数

题目就是求联通分支个数删除一个点,剩下联通分支个数为cnt,那么需要建立cnt-1边才能把这cnt个联通分支个数求出来怎么求联通分支个数呢可以用并查集,但并查集的话复杂度是O(m*logn*k)我这里用的是dfs,dfs的复杂度只要O((m+n)*k)这里k是指因为有k个点要查询,每个都要求一下删除后的联通分支数.题目没给定m的范围,所以如果m很大的话,dfs时间会比较小. for一遍1~n个点,每次从一个未标记的点u开始dfs,标记该dfs中访问过的点.u未标记过,说明之前dfs的时候没访问过

1017 Queueing at Bank (25 分)

1017 Queueing at Bank (25 分) Suppose a bank has K windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. All the customers have to wait in line behind the yellow line, until it is his/h