队列:动物收养所

问题

题目描述

有家动物收容所只收留猫和狗,但有特殊的收养规则。收养人有两种收养方式:第一种为直接收养所有动物中最早进入收容所的。第二种为选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的。给定一个操作序列代表所有事件。
若第一个元素为 1,则代表有动物进入收容所。第二个元素为动物的编号,正数代表狗,负数代表猫。
若第一个元素为 2,则代表有人收养动物。第二个元素若为 0,则采取第一种收养方式;若为1,则指定收养狗;若为-1,则指定收养猫。
请按顺序输出收养动物的序列。
若出现不合法的操作,即没有可以符合领养要求的动物,则将这次领养操作忽略。

输入

 第一个是n,它代表操作序列的次数。接下来是n行,每行有两个值m 和t,分别代表题目中操作的两个元素。

输出

 按顺序输出收养动物的序列,编号之间以空格间隔。

样例输入 

6
1 1
1 -1
2 0
1 2
2 -1
2 1 

样例输出 

1  -1  2

分析

        根据题目描述的先进先出方法,首先应该想到采用队列来实现。然而,如果只维护一个队列,那么对于直接收养所有动物中最早进入收容所的第一种收养方式,实现起来就会非常简单:只需每次取出队列头部的动物。但是,这样做的话,对于选择性地收养动物的第二种方式就会比较复杂,此时需要访问整个队列,以便找出第一个被访问的猫或第一个被访问的狗。

        因此,可以维护两个队列:一个队列用于存放狗,另一个队列用于存放猫。于是,对于选择性地收养动物的第二种方式,实现起来就会非常简单:根据要收养的是猫还是狗,从相应的队列中取出队列头部的动物。然而,对于第一种收养方式,需要判断两个队列头部的猫和狗哪个更先进入收容所,这时需要有一个标志进行判断。因此,每次在把动物放入它们对应的队列时,都要给它加一个次序标志。于是,只需比较两个队列头部动物的次序标志,就可实现第一种收养方式。

代码 

Java代码

import java.util.*;

class Animal{
    int number;
    int order;

    public Animal(int number,int order){
        this.number = number;
        this.order = order;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();
        int order = 1;

        Queue<Animal> dogs = new LinkedList<>();
        Queue<Animal> cats = new LinkedList<>();

        for(int i = 0;i < num;i++){
            int method,choice;
            method = scanner.nextInt();
            choice = scanner.nextInt();

            if(method == 1){
                if(choice > 0){
                    dogs.offer(new Animal(choice,order++));
                }else {
                    cats.offer(new Animal(choice,order++));
                }
            }else {
                if(choice == 0){
                    if(!dogs.isEmpty() && !cats.isEmpty()){
                        if(dogs.peek().order < cats.peek().order){
                            System.out.println(dogs.poll().number);
                        }else {
                            System.out.println(cats.poll().number);
                        }
                    } else if (!dogs.isEmpty() && cats.isEmpty()) {
                        System.out.println(dogs.poll().number);
                    }else if (dogs.isEmpty() && !cats.isEmpty()){
                        System.out.println(cats.poll().number);
                    }
                } else if (choice == 1) {
                    System.out.println(dogs.poll().number);
                } else if (choice == -1) {
                    System.out.println(cats.poll().number);
                }
            }
        }
    }
}

C+STL代码

#include <iostream>
#include <cstdio>
#include <queue>

using namespace std;

struct animal{
    int number;
    int order;
    
    animal(int _number,int _order):number(_number),order(_order){}    //构造方法
};

int main(){
    queue<animal> dog;
    queue<animal> cat;
    int num;
    scanf("%d", &num);
    int order = 0;
    
    for (int i = 0; i < num; i++) {
        int operation;
        int choice;
        scanf("%d %d", &operation, &choice);
                
        if(operation == 1){
            if(choice > 0){
                dog.push(animal(choice,order++));
            }else{
                cat.push(animal(choice,order++));
            }
        }else if (operation == 2){
            if(choice == 0){
                if(!dog.empty() && !cat.empty()){
                    if(dog.front().order < cat.front().order){
                        printf("%d",dog.front().number);
                        dog.pop();
                    }else{
                        printf("%d",cat.front().number);
                        cat.pop();
                    }
                }else if (!dog.empty() && cat.empty()){
                    printf("%d",dog.front().number);
                    dog.pop();
                }else if (dog.empty() && !cat.empty()){
                    printf("%d",cat.front().number);
                    cat.pop();
                }
            }else if (choice == 1){
                printf("%d",dog.front().number);
                dog.pop();
            }else if (choice == -1){
                printf("%d",cat.front().number);
                cat.pop();
            }
        }
    }
    
    return 0;
}

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沙河板混

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值