1 条题解

  • 0
    @ 2025-7-14 17:42:21

    方法思路

    1. 使用LinkedHashMap来维护队列,保持插入顺序并支持O(1)的删除操作
    2. 使用HashMap存储已离开队列的人及其购买的手办数量
    3. 当手办数量小于等于m时,队首的人会买走所有剩余手办,然后结束模拟
    4. 最后按字典序输出每个人购买的手办数量

    这种方法的优点是实现简单,避免了复杂的懒删除逻辑,直接使用LinkedHashMap的特性来维护队列顺序。

    代码实现

    Java
    import java.io.*;
    import java.util.*;
    
    public class Main {
        public static void main(String[] args) throws IOException {
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
            
            String[] split = in.readLine().split(" ");
            long n = Long.parseLong(split[0]); // 手办总数
            long m = Long.parseLong(split[1]); // 特殊规则阈值
            int q = Integer.parseInt(split[2]); // 事件数量
            
            // 使用LinkedHashMap维护队列,保持插入顺序
            Map<String, Long> queue = new LinkedHashMap<>();
            // 记录所有人购买的手办数量(包括离开队列的人)
            Map<String, Long> purchases = new HashMap<>();
            
            int index = 0;
            while (index < q) {
                String[] event = in.readLine().split(" ");
                int op = Integer.parseInt(event[0]);
                
                if (op == 1) { // 加入队列
                    String name = event[1];
                    queue.put(name, purchases.getOrDefault(name, 0L));
                } else if (op == 2) { // 离开队列
                    String name = event[1];
                    purchases.put(name, queue.get(name));
                    queue.remove(name);
                } else if (op == 3) { // 购买手办
                    long x = Long.parseLong(event[1]);
                    if (!queue.isEmpty()) {
                        // 获取队首的人
                        Map.Entry<String, Long> entry = queue.entrySet().iterator().next();
                        String frontPerson = entry.getKey();
                        
                        // 检查特殊规则
                        if (n - x <= m) {
                            // 如果剩余手办数量小于等于m,队首的人买走所有手办
                            queue.put(frontPerson, queue.getOrDefault(frontPerson, 0L) + n);
                            // 更新到purchases中
                            purchases.put(frontPerson, queue.get(frontPerson));
                            break; // 手办卖完,结束模拟
                        } else {
                            // 正常购买
                            queue.put(frontPerson, queue.getOrDefault(frontPerson, 0L) + x);
                            n -= x;
                            // 更新到purchases中
                            purchases.put(frontPerson, queue.get(frontPerson));
                        }
                    }
                } else if (op == 4) { // 查看队列人数
                    out.println(queue.size());
                }
                
                index++;
            }
            
            // 将队列中剩余的人的购买情况更新到purchases中
            for (Map.Entry<String, Long> entry : queue.entrySet()) {
                purchases.put(entry.getKey(), entry.getValue());
            }
            
            // 按字典序输出每个人购买的手办数量
            List<String> names = new ArrayList<>(purchases.keySet());
            Collections.sort(names);
            
            for (String name : names) {
                out.println(name + " " + purchases.get(name));
            }
            
            out.flush();
        }
    }
    
    
    Python
    import sys
    
    def solve():
        n, m, q = map(int, input().split())
        
        # 使用字典维护队列,保持插入顺序
        queue = {}  # 键是人名,值是购买的手办数量
        # 记录所有人购买的手办数量(包括离开队列的人)
        purchases = {}
        
        index = 0
        while index < q:
            event = input().split()
            op = int(event[0])
            
            if op == 1:  # 加入队列
                name = event[1]
                queue[name] = purchases.get(name, 0)
            
            elif op == 2:  # 离开队列
                name = event[1]
                purchases[name] = queue[name]
                del queue[name]
            
            elif op == 3:  # 购买手办
                x = int(event[1])
                if queue:
                    # 获取队首的人
                    front_person = next(iter(queue))
                    
                    # 检查特殊规则
                    if n - x <= m:
                        # 如果剩余手办数量小于等于m,队首的人买走所有手办
                        queue[front_person] = queue.get(front_person, 0) + n
                        # 更新到purchases中
                        purchases[front_person] = queue[front_person]
                        break  # 手办卖完,结束模拟
                    else:
                        # 正常购买
                        queue[front_person] = queue.get(front_person, 0) + x
                        n -= x
                        # 更新到purchases中
                        purchases[front_person] = queue[front_person]
            
            elif op == 4:  # 查看队列人数
                print(len(queue))
            
            index += 1
        
        # 将队列中剩余的人的购买情况更新到purchases中
        for name, amount in queue.items():
            purchases[name] = amount
        
        # 按字典序输出每个人购买的手办数量
        for name in sorted(purchases.keys()):
            print(f"{name} {purchases[name]}")
    
    solve()
    
    
    C++
    #include <iostream>
    #include <list>
    #include <unordered_map>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
    
        long long n, m;
        int q;
        cin >> n >> m >> q;
    
        list<string> queue;
        unordered_map<string, long long> purchases;
        bool sold_out = false;
    
        while (q--) {
            int op;
            cin >> op;
    
            if (sold_out) {
                continue;
            }
    
            if (op == 1) {
                string s;
                cin >> s;
                queue.push_back(s);
                if (purchases.find(s) == purchases.end()) {
                    purchases[s] = 0;
                }
            } else if (op == 2) {
                string s;
                cin >> s;
                for (auto it = queue.begin(); it != queue.end(); ++it) {
                    if (*it == s) {
                        queue.erase(it);
                        break;
                    }
                }
            } else if (op == 3) {
                long long x;
                cin >> x;
                if (!queue.empty()) {
                    string front_person = queue.front();
                    if (n - x <= m) {
                        purchases[front_person] += n;
                        n = 0;
                        sold_out = true;
                        queue.clear();
                    } else {
                        purchases[front_person] += x;
                        n -= x;
                    }
                }
            } else if (op == 4) {
                cout << queue.size() << '\n';
            }
        }
    
        for (const auto& person : queue) {
            purchases[person] = purchases[person];
        }
    
      
        vector<string> names;
        for (const auto& entry : purchases) {
            names.push_back(entry.first);
        }
        sort(names.begin(), names.end());
    
        for (const auto& name : names) {
            cout << name << " " << purchases[name] << '\n';
        }
    
        return 0;
    }
    
    • 1

    信息

    ID
    68
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    1
    已通过
    1
    上传者