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