1014 Waiting in Line (30 point(s)) - C语言 PAT 甲级

1014 Waiting in Line (30 point(s))

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 (N x M + 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 Ti 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, customeri 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 Specification:

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 Specification:

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

题目大意:

银行 8:00am 开始工作,N 个窗口,每个窗口容纳 M 个人排队,K 名顾客,每名顾客对应一个处理业务所需的时间,Q 次查询;求每次查询的顾客的结束时间;顾客 17:00 及 17:00 以后还未开始服务的,不再提供服务输出 sorry

顾客入队规则如下:

  • 顾客按输入顺序依次入队
  • 当窗口未满时,按窗口号从小到大,队列长度最小,进入对应窗口排队;窗口满,黄线外等候
  • 某一列结束一人,黄线外进一人;若同时多列结束,选择窗口号小的
设计思路:

转化为求顾客的入队时间,即可根据处理业务时间计算结束时间

  • 结构体,每位顾客的入队时间 pushtime,处理业务时间 time
  • 结构体,为每个窗口维护一个队列(入队过程中,此一维数组模拟循环队列,以防止数组越界,并节约空间),记录队首出队时间 poptime,队尾结束的时间 endtime
  1. 队列未满时,依次入队,入队过程中根据入队的顾客初始化队列
    • 初始化队列,此队列 poptime = 第一位顾客的处理时间,此队列结束时间 endtime = 第一位顾客业务时间
    • 继续入队列,此队列结束时间 endtime += 顾客业务时间累加
  2. 队列已满时,根据维护队列的 poptime,查询最先出队的顾客,此顾客出队列,黄线外下一顾客入队,出入队列过程更新此队列信息
    • 出队列,此队列 poptime += 队列中第二位顾客的处理时间
    • 入队列,此顾客的入队时间 pushtime = 此队列的 endtime,此队列结束时间 endtime += 此顾客业务时间
  3. 所有顾客入队完毕,其入队时间全部更新,即可查询

注:对 17:00 以前已经开始处理业务的顾客,不管处理到多晚,结束时间都如实输出,即 17:00 时银行不关门但不接受新业务;

1017 题不需要实际维护对应的队列,而本题需要,因为本题在队满出队时,必须要知道队列中第二位顾客的信息,才能更新此队列最新的出队时间,所以要维护完整的队列信息;

编译器:C (gcc)
#include <stdio.h>

struct window {
        int poptime;
        int endtime;
        int queue[11];
        int front, rear, length;
};

struct customer {
        int time;
        int pushtime;
};

int main(void)
{
        int n, m, k, q;
        struct window windows[21] = {0};
        struct customer customers[1001] = {0};
        int i, j;

        scanf("%d %d %d %d", &n, &m, &k, &q);
        int push = 0;
        for (i = 1; i <= k; i++) {
                scanf("%d",&customers[i].time);

                if (i <= m * n) {
                        push = push % n;
                        push++;
                } else {
                        push = 1;
                        for (j = 1; j <= n; j++) {
                                if (windows[j].poptime < windows[push].poptime)
                                push = j;
                        }
                }

                if (windows[push].length == 0)
                        windows[push].poptime = customers[i].time;
                if (windows[push].length == m) {
                        windows[push].front++;windows[push].front %= 11;
                        windows[push].length--;
                        windows[push].poptime += customers[windows[push].queue[windows[push].front]].time;
                }
                customers[i].pushtime = windows[push].endtime;
                windows[push].endtime += customers[i].time;
                windows[push].queue[windows[push].rear] = i;
                windows[push].rear++;windows[push].rear %= 11;
                windows[push].length++;
        }
        for (i = 0; i < q; i++) {
                int tmp, query;
                scanf("%d", &query);
                tmp = customers[query].pushtime + customers[query].time;
                if (customers[query].pushtime >= (17 - 8) * 60)
                        printf("Sorry\n");
                else
                        printf("%02d:%02d\n", tmp / 60 + 8, tmp % 60);
        }
        return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
既然你想了解短作业优先算法的C语言编程实现,那么我们可以先了解一下这种调度算法的基本思想。短作业优先算法又称为SJF算法,它的核心思想是优先调度执行时间短的进程。对于所有正在等待处理器的进程,按照它们的执行时间升序进行排序,然后选择执行时间最短的进程先被调度执行。这种算法相对其他调度算法来说,它能够有效的缩短进程的等待时间,提高系统的响应速度。下面是一个具体实现的C语言代码范例: ```c #include <stdio.h> #include <stdlib.h> #define max 50 struct process { int pid; // 进程ID int burst_time; // 执行时间 int waiting_time; // 等待时间 int turnaround_time; // 周转时间 }; int sjf(struct process p[], int n) { // 短作业优先调度算法 int i, j, shortest; float avwt = 0; // 平均等待时间 float avtat = 0; // 平均周转时间 for (i = 0; i < n; i++) { shortest = i; for (j = i + 1; j < n; j++) { if (p[j].burst_time < p[shortest].burst_time) { shortest = j; } } struct process temp = p[i]; p[i] = p[shortest]; p[shortest] = temp; p[i].waiting_time = 0; p[i].turnaround_time = p[i].burst_time; for (j = 0; j < i; j++) { p[i].waiting_time += p[j].burst_time; } avwt += p[i].waiting_time; avtat += p[i].turnaround_time; } printf("\nProcess\tBurst Time\tWaiting Time\tTurnaround Time"); for (i = 0; i < n; i++) { printf("\n%d\t\t%d\t\t%d\t\t%d", p[i].pid, p[i].burst_time, p[i].waiting_time, p[i].turnaround_time); } printf("\n\nAverage waiting time = %f", avwt / n); printf("\nAverage turnaround time = %f", avtat / n); } int main() { struct process p[max]; int n, i; printf("Enter the number of processes: "); scanf("%d", &n); printf("\nEnter the burst time of each process:\n"); for (i = 0; i < n; i++) { printf("Process %d: ", i + 1); p[i].pid = i + 1; scanf("%d", &p[i].burst_time); } sjf(p, n); return 0; } ``` 上述代码中,我们首先定义了一个包含进程ID、执行时间、等待时间、周转时间等信息的结构体`process`,然后定义了一个`sjf`函数,该函数实现了短作业优先调度算法,返回平均等待时间和平均周转时间。在`main`函数中,我们首先输入了进程数和每个进程的执行时间,并调用`sjf`函数进行调度。最后输出每个进程的执行时间、等待时间、周转时间,以及平均等待时间和平均周转时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值