原题:猫狗收容所
有家动物收容所只收留猫和狗,但有特殊的收养规则,收养人有两种收养方式,第一种为直接收养所有动物中最早进入收容所的,第二种为选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的。
给定一个操作序列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;
}
}; 
京公网安备 11010502036488号