PAT甲级 1017 Queueing at Bank (25) 模拟

本文介绍了一个银行排队模拟问题的解决方案,通过优先队列记录每个窗口的状态,并为每位顾客分配最早可用的窗口,以此来计算顾客的平均等待时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

1017 Queueing at Bank (25)


题意

银行有n个顾客,k个窗口,求顾客的平均等待时间

解题思路

每次取最早可以使用的窗口就行了

Code

#include <bits/stdc++.h>

using namespace std;

struct Time
{
    int hh, mm, ss;
    bool friend operator < (Time a,Time b)
    {
        if(a.hh!=b.hh)
            return a.hh > b.hh;
        if(a.mm!=b.mm)
            return a.mm > b.mm;
        return a.ss > b.ss;
    }
    int friend operator - (Time a, Time b)
    {
        return a.hh * 3600 + a.mm * 60 + a.ss - b.hh * 3600 - b.mm * 60 - b.ss;
    }
    Time friend operator + (Time a,Time b)
    {
        Time sum = Time{a.hh+b.hh, a.mm+b.mm, a.ss+b.ss};
        if(sum.ss>=60)
        {
            sum.ss -= 60;
            sum.mm++;
        }
        if(sum.mm>=60)
        {
            sum.mm -= 60;
            sum.hh++;
        }
        return sum;
    }
};

struct Arr
{
    Time time;
    int p;
};

bool cmp(Arr a,Arr b)
{
    if(a.time.hh!=b.time.hh)
        return a.time.hh< b.time.hh;
    if(a.time.mm!=b.time.mm)
        return a.time.mm < b.time.mm;
    return a.time.ss < b.time.ss;
}
const Time open = Time{8, 0, 0},
           close = Time{17, 0, 0};
const int maxn = 10000 + 5;

priority_queue<Time> W;//window
Arr a[maxn];
int n, k;

int main(int argc, char const *argv[])
{
    //freopen("input.txt", "r", stdin);
    cin >> n >> k;
    for(size_t i = 0; i < k; i++)
        W.push(Time{8, 0, 0});
    int sum = 0, cnt = 0;
    for (int i = 0; i < n;i++)
    {
        scanf("%d:%d:%d", &a[i].time.hh, &a[i].time.mm, &a[i].time.ss);
        scanf("%d", &a[i].p);
    }
    sort(a, a + n, cmp);
    for (size_t i = 0; i < n; i++)
    {
        Time arr=a[i].time;
        int p=a[i].p;
        if (arr < close)
            continue;
        cnt++;
        Time w = W.top();
        W.pop();
        //printf("%d:%d:%d - %d:%d:%d\n",w.hh,w.mm,w.ss,arr.hh,arr.mm,arr.ss);
        if (w <arr)
        {
            sum += (w - arr);
        }
        else
        {
            w = arr;
        }
        //cout << sum << ' ' << p << endl;
        W.push(w + Time{0, p, 0});
    }
    if(cnt==0)
        cout << "0.0" << endl;
    else
    {
        printf("%.1f\n", double(sum)/60 / cnt);
    }
    return 0;
}
### 银行排队问题的Python实现 银行排队问题是典型的并行处理和任务分配场景,可以通过ZeroMQ框架中的Ventilator-Worker-Sink模型来解决[^1]。以下是基于该模型的一个简单Python实现: #### ZeroMQ Ventilator 实现 Ventilator负责生成任务并将它们发送给Workers。 ```python import zmq import time context = zmq.Context() # Socket to send tasks to workers sender = context.socket(zmq.PUSH) sender.bind("tcp://*:5557") print("Press Enter when the workers are ready...") _ = input() print("Sending tasks to workers...") # Send out tasks total_msec = 0 for task_nbr in range(100): workload = int((task_nbr * task_nbr) % 100 + 1) # Some random work load total_msec += workload sender.send_string(str(workload)) print(f"Total expected cost: {total_msec} msec") time.sleep(1) # Give 0MQ time to deliver ``` #### ZeroMQ Worker 实现 Worker接收来自Ventilator的任务并执行计算后将结果返回给Sink。 ```python import zmq import sys import time context = zmq.Context() # Socket to receive messages on receiver = context.socket(zmq.PULL) receiver.connect("tcp://localhost:5557") # Socket to send messages to sender = context.socket(zmq.PUSH) sender.connect("tcp://localhost:5558") while True: s = receiver.recv_string() print(f"Received request: {s}") # Do some 'work' time.sleep(int(s) / 10) # Send results to sink sender.send(b'') ``` #### ZeroMQ Sink 实现 Sink收集所有Worker的结果,并统计完成时间。 ```python import zmq import time context = zmq.Context() # Socket to collect worker responses receiver = context.socket(zmq.PULL) receiver.bind("tcp://*:5558") # Wait for start of batch s = receiver.recv() # Start our clock now tstart = time.time() # Process 100 confirmations for task_nbr in range(100): s = receiver.recv() if task_nbr % 10 == 0: sys.stdout.write(':') else: sys.stdout.write('.') sys.stdout.flush() # Calculate and report duration of batch tend = time.time() print(f"\nTotal elapsed time: {(tend-tstart)*1000} msec") ``` 上述代码展示了如何通过ZeroMQ构建一个简单的分布式任务管理系统[^2]。对于银行排队问题,可以将其视为多个客户作为任务被分配到不同的柜员(即Worker),而最终的结果由Sink汇总。 此外,在高并发环境下,还需要注意内存管理和I/O性能优化[^3]。建议使用缓存机制减少磁盘操作频率,并利用消息队列实现各模块间的异步通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值