问题
题目描述
有家动物收容所只收留猫和狗,但有特殊的收养规则。收养人有两种收养方式:第一种为直接收养所有动物中最早进入收容所的。第二种为选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的。给定一个操作序列代表所有事件。
若第一个元素为 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;
}