原题:猫狗收容所
有家动物收容所只收留猫和狗,但有特殊的收养规则,收养人有两种收养方式,第一种为直接收养所有动物中最早进入收容所的,第二种为选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的。
给定一个操作序列int[][2] ope(C++中为vector<vector<int>>)代表所有事件。若第一个元素为1,则代表有动物进入收容所,第二个元素为动物的编号,正数代表狗,负数代表猫;若第一个元素为2,则代表有人收养动物,第二个元素若为0,则采取第一种收养方式,若为1,则指定收养狗,若为-1则指定收养猫。请按顺序返回收养的序列。若出现不合法的操作,即没有可以符合领养要求的动物,则将这次领养操作忽略。</int>
题解
用两个 deque 分开存🐱和🐶,附带计数,以供按顺序出院时用(按种类出院直接先进先出即可)
Python
from collections import deque CAT=0 DOG=1 class CatDogAsylum: def asylum(self, ope): q = [deque(), deque()] cnt = 0 res = [] for op, opr in ope: if op == 1: q[opr > 0].append((opr, cnt)) cnt += 1 else: if opr == 0: nxt = q[CAT] or q[DOG] try: nxt = q[CAT] if q[CAT][0][1] < q[DOG][0][1] else q[DOG] except IndexError: # one of two queues is empty pass else: nxt = q[opr > 0] if nxt: opr, _ = nxt.popleft() res.append(opr) return res
C++
#include <exception> class CatDogAsylum { public: vector<int> asylum(vector<vector<int> > ope) { vector<int> ret; deque<pair<int, int>> q[2]; int cnt = 0; for (auto &v: ope) { auto op = v[0], opr = v[1]; if (op == 1) { q[opr>0].push_back(make_pair(opr, cnt++)); } else { #define num first #define idx second auto *nxt = &q[0]; if (opr == 0) { nxt = q[0].size() ? &q[0] : &q[1]; try { // use at to trigger out_of_range auto t = q[0].at(0).idx < q[1].at(0).idx ? &q[0] : &q[1]; nxt = t; } catch (std::out_of_range &e) {} } else nxt = &q[opr>0]; if (nxt->size()) { ret.emplace_back(nxt->front().num); nxt->pop_front(); } #undef idx #undef num } } return ret; } };