【题解】银行排队
【题目描述】
我们大多都有在银行排队的经历,唉,那坑爹的排队啊!现在就让我们来算算我们这些客户平均需要等多久吧。
每天刚开始时银行会开m个窗口来为我们total个客户办理业务,当有客户需要办理业务时,先选择可以办理业务的窗口,如果有多个窗口可以办理业务就选择空闲时间最长的窗口,如果有多个窗口空闲的时间一样长,则选择序号小的窗口办理业务。假设我们每个人来到的时间和办理业务所需要的时间(为了简化问题,采用整数表示时间)都知道了。现在请你算算我们平均需要等待多久呢?
【输入描述】
有多组测试数据,每组数据开始有两个正整数m(<20)和total(<200),后面有total对整数,对应客户先后到来的时间以及办理业务所需的时间。
【输出描述】
平均等待的时间,保留两位小数。
【样例输入】
2 6 1 3 4 1 5 3 9 2 13 4 13 3 3 14 0 3 2 2 2 4 5 4 7 2 11 3 12 3 12 4 12 1 13 3 15 4 19 1 22 3 23 2 2 5 0 6 0 5 0 6 7 1 7 2
【样例输出】
0.00 0.29 1.20
【题目分析】
贪心策略。客户到达时,选择当前最早空闲的窗口(即该窗口队尾客户的离开时间最早)。
如果客户到达时窗口仍被占用,则需等待(等待时间 = 窗口空闲时间 - 客户到达时间)。
如果客户到达时窗口空闲,则直接开始处理(等待时间 = 0)。
核心算法流程:
int processCustomer(int windows[], Customer customer, int m) { // 1. 选择最优窗口(当前最早空闲的窗口) int best = 0; for (int i = 1; i < m; ++i) { if (windows[i] < windows[best]) { best = i; } } // 2. 计算等待时间 int wait_time = 0; if (customer.arrive_time <= windows[best]) { // 需要等待 wait_time = windows[best] - customer.arrive_time; windows[best] += customer.process_time; // 更新窗口时间 } else { // 无需等待,直接占用窗口 windows[best] = customer.arrive_time + customer.process_time; } return wait_time; }
选择最优窗口:
遍历所有窗口,找到
windows[i]
最小的窗口(即最早空闲的窗口)。计算等待时间:
如果客户到达时窗口仍被占用(
arrive_time <= windows[best]
),则等待时间为windows[best] - arrive_time
。否则,客户无需等待,窗口空闲时间更新为
arrive_time + process_time
。返回当前客户的等待时间。
例子:
输入:
2 4 0 5 1 3 2 1 3 2
计算过程:
客户 | 到达时间 | 处理时间 | 选择窗口 | 窗口空闲时间 | 等待时间 |
---|---|---|---|---|---|
1 | 0 | 5 | 0 | 5 | 0 |
2 | 1 | 3 | 1 | 4 | 0 |
3 | 2 | 1 | 1 | 5 | 2 |
4 | 3 | 2 | 0 | 7 | 2 |
总等待时间 = 0 + 0 + 2 + 2 = 4
平均等待时间 = 4 / 4 = 1.00
输出:
1.00
【参考答案】
#include <bits/stdc++.h> using namespace std; // 客户数据结构(原C代码的arri/stay变量) struct Customer { int arrive_time; // 到达时间 int process_time; // 处理时间 }; Customer customers[1000]; // 客户数组 int windows[20]; // 窗口队列 /** * 处理单个客户并返回更新后的窗口时间 customer 当前客户数据(值传递) m 窗口总数 * @return 当前客户的等待时间 */ int processCustomer(Customer customer, int m) { int best = 0; // 选择最优窗口:队尾离开时间最早的窗口 for (int i = 1; i < m; ++i) { if (windows[i] < windows[best]) { best = i; } } int wait_time = 0; // 判断是否需要等待 if (customer.arrive_time <= windows[best]) { wait_time = windows[best] - customer.arrive_time; windows[best] += customer.process_time; // 更新窗口时间 } else { windows[best] = customer.arrive_time + customer.process_time; } return wait_time; // 返回当前客户的等待时间 } int main() { int m; // 窗口数 int total; // 客户总数 // 多组测试数据循环 while (cin >> m >> total) { // 初始化窗口时间 for (int i = 0; i < m; ++i) { windows[i] = 0; } double total_wait = 0.0; // 总等待时间 // 读取所有客户数据 for (int i = 0; i < total; ++i) { cin >> customers[i].arrive_time >> customers[i].process_time; } // 处理每个客户并累加等待时间 for (int i = 0; i < total; ++i) { total_wait += processCustomer(customers[i], m); } // 输出平均等待时间 printf("%.2lf\n",(total_wait / total) ); } return 0; }
扫描二维码推送至手机访问。
版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。