• 1014. Waiting in Line (30)


    题目连接:https://www.patest.cn/contests/pat-a-practise/1014

    原题如下:

    Suppose a bank has N windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. The rules for the customers to wait in line are:

    • The space inside the yellow line in front of each window is enough to contain a line with M customers. Hence when all the N lines are full, all the customers after (and including) the (NM+1)st one will have to wait in a line behind the yellow line.
    • Each customer will choose the shortest line to wait in when crossing the yellow line. If there are two or more lines with the same length, the customer will always choose the window with the smallest number.
    • Customer[i] will take T[i] minutes to have his/her transaction processed.
    • The first N customers are assumed to be served at 8:00am.

    Now given the processing time of each customer, you are supposed to tell the exact time at which a customer has his/her business done.

    For example, suppose that a bank has 2 windows and each window may have 2 custmers waiting inside the yellow line. There are 5 customers waiting with transactions taking 1, 2, 6, 4 and 3 minutes, respectively. At 08:00 in the morning, customer1 is served at window1 while customer2 is served at window2. Customer3 will wait in front of window1 and customer4 will wait in front of window2. Customer5 will wait behind the yellow line.

    At 08:01, customer1 is done and customer5 enters the line in front of window1 since that line seems shorter now. Customer2 will leave at 08:02, customer4 at 08:06, customer3 at 08:07, and finally customer5 at 08:10.

    Input

    Each input file contains one test case. Each case starts with a line containing 4 positive integers: N (<=20, number of windows), M (<=10, the maximum capacity of each line inside the yellow line), K (<=1000, number of customers), and Q (<=1000, number of customer queries).

    The next line contains K positive integers, which are the processing time of the K customers.

    The last line contains Q positive integers, which represent the customers who are asking about the time they can have their transactions done. The customers are numbered from 1 to K.

    Output

    For each of the Q customers, print in one line the time at which his/her transaction is finished, in the format HH:MM where HH is in [08, 17] and MM is in [00, 59]. Note that since the bank is closed everyday after 17:00, for those customers who cannot be served before 17:00, you must output "Sorry" instead.

    Sample Input
    2 2 7 5
    1 2 6 4 3 534 2
    3 4 5 6 7
    
    Sample Output
    08:07
    08:06
    08:10
    17:00
    Sorry
    
    这道题目我就是用队列去模拟,感觉需要理顺逻辑关系。自己的代码中冗杂的地方就是只有通过出队才能统计时间。也不想改了……
    大致思路如下:
    1、将N*M个顾客入队;
    2、将剩余的顾客入队(伴随着出队),此时要进行判断哪个窗口的时间最短;
    3、将不空的队列进行出队,至此,每位顾客的时间都已经做了统计。

    容易出错的地方是要看清楚“如果开始服务的时间大于或等于17:00”,则输出Sorry,而不是结束的时间
    代码如下:
      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<stdbool.h>
      4 #define MAXK 1005
      5 int T[MAXK]={0};
      6 int N,M,K,q;
      7 int customer[MAXK];
      8 
      9 typedef struct WNode{
     10     int time;
     11 }Win;
     12 
     13 Win Window[MAXK];
     14 
     15 typedef struct QNode{
     16     int front;
     17     int rear;
     18     int Maxsize;
     19     int *Customer;
     20     int CustomerIn;
     21 }Quenue;
     22 
     23 Quenue Q[MAXK];
     24 
     25 void CreatQ(int i)
     26 {
     27     Q[i].front=Q[i].rear=0;
     28     Q[i].Maxsize=M;
     29     Q[i].Customer=(int *)malloc(M*(sizeof(int)));
     30     Q[i].CustomerIn=0;
     31 
     32 }
     33 
     34 bool IsEmptyQ(int i)
     35 {
     36     return (Q[i].rear==Q[i].front);
     37 }
     38 
     39 int Pop(int i)
     40 {
     41     if (!IsEmptyQ(i))
     42     {
     43         int tmp,out;
     44         Q[i].front=(Q[i].front+1)%(Q[i].Maxsize);
     45         tmp=Q[i].Customer[Q[i].front];
     46         out=Q[i].CustomerIn;
     47         Q[i].CustomerIn=tmp;
     48 
     49         return out;
     50     }
     51 }
     52 
     53 bool IsFull(int i)
     54 {
     55     return ((Q[i].rear+1)%(Q[i].Maxsize)==Q[i].front);
     56 }
     57 
     58 void Add(int i,int x)
     59 {
     60     if (!IsFull(i))
     61     {
     62         Q[i].rear=(Q[i].rear+1)%(Q[i].Maxsize);
     63         Q[i].Customer[Q[i].rear]=x;
     64     }
     65 }
     66 
     67 int MinWindowsTime()
     68 {
     69     int i;
     70     int Mintime=65535,Mini=0;
     71     for (i=1;i<=N;i++)
     72     {
     73         if (Window[i].time<Mintime)
     74         {
     75             Mintime=Window[i].time;
     76             Mini=i;
     77         }
     78     }
     79     return Mini;
     80 }
     81 
     82 
     83 int main()
     84 {
     85 
     86     scanf("%d %d %d %d",&N,&M,&K,&q);
     87     int i,j;
     88     for (i=1;i<=K;i++)
     89     {scanf("%d",&T[i]);
     90      CreatQ(i);
     91     }
     92 
     93     //第一批顾客,N个窗口
     94     for (i=1;i<=N*M;i++)
     95     {
     96      Window[i].time=480;
     97         if (i>K)break;
     98         if (i<=N)
     99         {Q[i].CustomerIn=i;
    100         Window[i].time+=T[i];
    101         }
    102         else
    103         {
    104             j=i%N;
    105             if (j==0)j=N;
    106             Add(j,i);
    107         }
    108     }
    109     //剩余的顾客,一共K个顾客
    110     int c;
    111     for (;i<=K;i++)  //将每个顾客进行入队处理,先出队(同时统计其时间)再入队
    112     {
    113             int t=MinWindowsTime();  //最先有空位的窗口
    114             if (t!=0)
    115             {
    116                 if (!IsEmptyQ(t))
    117                 {c=Pop(t);
    118                 customer[c]=Window[t].time;
    119                 Window[t].time+=T[Q[t].CustomerIn];
    120                 Add(t,i);
    121                 }
    122             }
    123     }
    124 
    125     for (i=1;i<=N;i++)   // 对于每个窗口,将还在队伍中的顾客进行出队,并统计时间
    126     {
    127         while (!IsEmptyQ(i))
    128         {c=Pop(i);
    129         customer[c]=Window[i].time;
    130         Window[i].time+=T[Q[i].CustomerIn];
    131         }
    132          if (IsEmptyQ(i)&& Q[i].CustomerIn!=0)
    133         {
    134             c=Q[i].CustomerIn;
    135             customer[c]=Window[i].time;
    136             Q[i].CustomerIn=0;
    137             }
    138         }
    139 
    140     int v,h,m;
    141     while (q--)
    142     {
    143         scanf("%d",&v);
    144         if (customer[v]-T[v]<1020)
    145         {h=customer[v]/60;
    146         m=customer[v]%60;
    147         printf("%02d:%02d
    ",h,m);}
    148         else printf("Sorry
    ");
    149     }
    150     return 0;
    151 }
    View Code

    陈越老师好像讲过这个问题,有时间再把她的思路方法总结下吧。

  • 相关阅读:
    误删表空间处理办法
    一步步开发网站系列-网站界面
    webstorm ftp发布问题
    TP5接受Vue跨域请求
    tp5上传图片添加永久素材到微信公众号
    将博客搬至CSDN
    swoole http_server 多进程并使用多进程处理消息
    高并发下,php与redis实现的抢购、秒杀功能
    SVN服务器搭建
    web服务器安全笔记
  • 原文地址:https://www.cnblogs.com/wuxiaotianC/p/6351281.html
Copyright © 2020-2023  润新知