题解:队列模拟
题解:队列模拟
1.数据结构存储
我们首先设计一个订单的数据结构,每个订单会包含以下信息:
:用户唯一标识。
:请求类型(0表示订单请求,1表示助力请求)。
:订单唯一标识。
:订单请求的票数。
:订单请求在输入中的顺序编号。
其次,我们需要构建一个 订单位置映射表:使用哈希表记录每个订单在中的位置,方便快速定位订单。同时维护一个助力用户集合:使用哈希集合记录已经参与助力的用户,确保每个用户只能助力一次。
2.输入数据处理
然后我们逐行读取每行输入,如果是订单请求(4个字段),将其解析为对象并加入队列,同时更新,如果是助力请求(3个字段),从以下几个方面检查助力请求是否有效:
条件1:目标订单是否存在。
条件2:助力用户是否重复助力。
条件3:助力是否过期(当前请求编号与目标订单编号差值不超过30)。
若助力有效,则将目标订单与前一个订单交换位置,并更新。
3.订单处理
遍历队列,依次处理每个订单请求:若当前订单的请求票数小于等于剩余票数,则该订单成功,减少剩余票数。否则,该订单失败。
C++
#include <bits/stdc++.h> using namespace std; struct Order { string uid; int type; string orderid; int reqnum; int idx; }; int main() { int m; cin >> m; cin.ignore(); // 忽略多余的换行符 string line; vector<Order> orders; unordered_map<string, int> oloc; unordered_set<string> helper; int cnt = 0; while (getline(cin, line) && cnt < 10000) { if (line.empty()) { continue; } cnt++; stringstream ss(line); string word; vector<string> tokens; while (ss >> word) { tokens.push_back(word); } // 当前是购票请求 if (tokens.size() == 4) { Order o; o.uid = tokens[0]; o.type = 0; o.orderid = tokens[2]; o.reqnum = stoi(tokens[3]); o.idx = cnt; orders.push_back(o); oloc[o.orderid] = orders.size() - 1; } else if (tokens.size() == 3) { // 当前是助力请求 string helperuid = tokens[0]; string helperoid = tokens[2]; if (!oloc.count(helperoid)) { continue; } int loc = oloc[helperoid]; Order& oo = orders[loc]; // 不允许自己给自己助力,不允许重复助力 if (helperuid == oo.uid || helper.count(helperuid)) { continue; } helper.insert(helperuid); // 过期助力,忽略 if (cnt - oo.idx > 30) { continue; } if (loc == 0) { continue; } int prev = loc - 1; swap(orders[prev], orders[loc]); oloc[orders[prev].orderid] = prev; oloc[orders[loc].orderid] = loc; } } int remain = m, on = orders.size(); for (int i = 0; i < on; i++) { cout << orders[i].uid << " " << orders[i].orderid << " " << orders[i].reqnum; if (orders[i].reqnum <= remain) { cout << " success" << endl; remain -= orders[i].reqnum; } else { cout << " failure" << endl; } } return 0; }
Java
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int m; // 总余票数 m = scanner.nextInt(); // 输入总余票数 scanner.nextLine(); // 忽略多余的换行符 // 定义结构体 Order,用于存储订单信息 class Order { String uid; int type; String orderid; int reqnum; int idx; Order(String uid, int type, String orderid, int reqnum, int idx) { this.uid = uid; this.type = type; this.orderid = orderid; this.reqnum = reqnum; this.idx = idx; } } List<Order> orders = new ArrayList<>(); // 存储订单列表 Map<String, Integer> oloc = new HashMap<>(); // 存储订单ID到订单索引的映射 Set<String> helper = new HashSet<>(); // 存储已经助力的用户ID int cnt = 0; // 当前处理的请求总数 // 循环读取每一行输入,直到遇到空行或请求总数达到 10000 while (scanner.hasNextLine() && cnt < 10000) { String line = scanner.nextLine(); if (line.isEmpty()) { continue; } cnt++; Scanner lineScanner = new Scanner(line); List<String> tokens = new ArrayList<>(); while (lineScanner.hasNext()) { tokens.add(lineScanner.next()); } lineScanner.close(); // 当前是购票请求 if (tokens.size() == 4) { Order o = new Order(tokens.get(0), 0, tokens.get(2), Integer.parseInt(tokens.get(3)), cnt); orders.add(o); oloc.put(o.orderid, orders.size() - 1); } else if (tokens.size() == 3) { // 当前是助力请求 String helperuid = tokens.get(0); String helperoid = tokens.get(2); if (!oloc.containsKey(helperoid)) { continue; } int loc = oloc.get(helperoid); Order oo = orders.get(loc); // 不允许自己给自己助力,不允许重复助力 if (helperuid.equals(oo.uid) || helper.contains(helperuid)) { continue; } helper.add(helperuid); // 过期助力,忽略 if (cnt - oo.idx > 30) { continue; } if (loc == 0) { continue; } int prev = loc - 1; // 交换订单位置 Collections.swap(orders, prev, loc); oloc.put(orders.get(prev).orderid, prev); oloc.put(orders.get(loc).orderid, loc); } } int remain = m, on = orders.size(); // 当前剩余票数和订单数量 // 按调整后的排队顺序依次处理每个订单请求 for (int i = 0; i < on; i++) { System.out.print(orders.get(i).uid + " " + orders.get(i).orderid + " " + orders.get(i).reqnum); if (orders.get(i).reqnum <= remain) { System.out.println(" success"); remain -= orders.get(i).reqnum; // 更新剩余票数 } else { System.out.println(" failure"); // 输出请求失败信息 } } scanner.close(); } }
Python
# 定义结构体 Order,用于存储订单信息 class Order: def __init__(self, uid, type, orderid, reqnum, idx): self.uid = uid self.type = type self.orderid = orderid self.reqnum = reqnum self.idx = idx # 读取总余票数 m = int(input().strip()) # 存储订单列表 orders = [] # 存储订单ID到订单索引的映射 oloc = {} # 存储已经助力的用户ID helper = set() cnt = 0 # 当前处理的请求总数 # 循环读取每一行输入,直到遇到空行或请求总数达到 10000 try: while True: line = input().strip() if line == "": break cnt += 1 if cnt > 10000: continue tokens = line.split() # 当前是购票请求 if len(tokens) == 4: o = Order(tokens[0], 0, tokens[2], int(tokens[3]), cnt) orders.append(o) oloc[o.orderid] = len(orders) - 1 elif len(tokens) == 3: # 当前是助力请求 helperuid = tokens[0] helperoid = tokens[2] if helperoid not in oloc: continue loc = oloc[helperoid] oo = orders[loc] # 不允许自己给自己助力,不允许重复助力 if helperuid == oo.uid or helperuid in helper: continue helper.add(helperuid) # 过期助力,忽略 if cnt - oo.idx > 30: continue if loc == 0: continue prev = loc - 1 # 交换订单位置 orders[prev], orders[loc] = orders[loc], orders[prev] oloc[orders[prev].orderid] = prev oloc[orders[loc].orderid] = loc except EOFError: pass # 处理输入结束的情况 remain = m # 当前剩余票数 on = len(orders) # 订单数量 # 按调整后的排队顺序依次处理每个订单请求 for i in range(on): print(f"{orders[i].uid} {orders[i].orderid} {orders[i].reqnum}", end=" ") if orders[i].reqnum <= remain: print("success") remain -= orders[i].reqnum # 更新剩余票数 else: print("failure") # 输出请求失败信息