猫狗队列

题目描述:

实现一种猫狗队列的结构,要求如下:

1.用户可以调用 add 方法将 cat 或者 dog 放入队列中

2.用户可以调用 pollAll 方法将队列中的 cat 和 dog 按照进队列的先后顺序依次弹出

3.用户可以调用 pollDog 方法将队列中的 dog 按照进队列的先后顺序依次弹出

4.用户可以调用 pollCat 方法将队列中的 cat 按照进队列的先后顺序依次弹出

5.用户可以调用 isEmpty 方法检查队列中是否还有 dog 或 cat

6.用户可以调用 isDogEmpty 方法检查队列中是否还有 dog

7.用户可以调用 isCatEmpty 方法检查队列中是否还有 cat

输入描述:
第一行输入一个整数 n 表示 用户的操作总次数。

以下 n行 每行表示用户的一次操作

每行的第一个参数为一个字符串 s,若 s = “add”, 则后面接着有 “cat x”(表示猫)或者“dog x”(表示狗),其中的 x 表示猫狗的编号。
输出描述:
对于每个操作:

若为 “add”,则不需要输出。

以下仅列举几个代表操作,其它类似的操作输出同理。

若为 “pollAll”,则将队列中的 cat 和 dog 按照进队列的先后顺序依次弹出。(FIFO),格式见样例。

若为 "isEmpty",则检查队列中是否还有 dog 或 cat, 为空则输出 “yes”, 否则输出 “no”。
示例1
输入
11
add cat 1
add dog 2
pollAll
isEmpty
add cat 5
isDogEmpty
pollCat
add dog 10
add cat 199
pollDog
pollAll
输出
cat 1
dog 2
yes
yes
cat 5
dog 10
cat 199
备注:

1 ≤ n ≤ 1 0 6 1 \leq n \leq 10^6 1n106

保证每个猫和狗的编号x都不相同且 1 ≤ x ≤ 1 0 6 1 \leq x \leq 10^6 1x106

保证没有不合法的操作

题解:

此题若只用一个队列的话,每次删除所有的猫或狗时,需要遍历整个队列,复杂度过高;可以考虑使用两个队列分别存储猫和狗,这样在只删除一种时,在对应的队列上进行操作即可。但是在执行 popAll 指令时出现一个问题:因为题目要求按照入队的先后顺序打印它们的信息,怎么知道它们入队的先后顺序呢?我们可以为每个入队的动物添加一个时间戳,记录它们入队的先后顺序,这样在删除整个队列时,只需要比较两个队列的队首元素时间戳大小,便可以知道入队的先后顺序。

代码:
#include <cstdio>
#include <queue>

using namespace std;

typedef pair<int, int> PII;

queue<PII> dog, cat;

int main(void) {
    char op[11];
    char type[4];
    int id, n;
    scanf("%d", &n);
    int counter = 0;
    while (n--) {
        scanf("%s", op);
        if (op[0] == 'a') {
            scanf("%s%d", type, &id);
            if (type[0] == 'c') {
                cat.push(PII(id, counter));
            } else {
                dog.push(PII(id, counter));
            }
            ++counter;
        } else if (op[0] == 'p') {
            if (op[4] == 'A') {
                while (!dog.empty() && !cat.empty()) {
                    if (dog.front().second < cat.front().second) {
                        printf("dog %d\n", dog.front().first);
                        dog.pop();
                    } else {
                        printf("cat %d\n", cat.front().first);
                        cat.pop();
                    }
                }
                while (!dog.empty()) {
                    printf("dog %d\n", dog.front().first);
                    dog.pop();
                }
                while (!cat.empty()) {
                    printf("cat %d\n", cat.front().first);
                    cat.pop();
                }
            } else if (op[4] == 'D') {
                while (!dog.empty()) {
                    printf("dog %d\n", dog.front().first);
                    dog.pop();
                }
            } else {
                while (!cat.empty()) {
                    printf("cat %d\n", cat.front().first);
                    cat.pop();
                }
            }
        } else {
            if (op[2] == 'E') {
                printf("%s\n", (dog.empty() && cat.empty() ? "yes" : "no"));
            } else if (op[2] == 'D') {
                printf("%s\n", (dog.empty() ? "yes" : "no"));
            } else {
                printf("%s\n", (cat.empty() ? "yes" : "no"));
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值