华为OD机试双机位A卷 - 特异性双端队列 (Python & C/C++ & JAVA & JS & GO) - 指南
华为OD机试双机位A卷真题 - 特异性双端队列
2025华为OD机试双机位A卷 - 华为OD上机考试双机位A卷 100分题型
华为OD机试双机位A卷真题目录点击查看: 华为OD机试双机位A卷真题题库目录|机考题库 + 算法考点详解
题目描述
有一个特异性的双端队列,该队列可以从头部或尾部添加数据,但是只能从头部移出数据。
小明依次执行2n个指令往队列中添加数据和移出数据。其中n个指令是添加数据(可能从头部添加、也可能从尾部添加),依次添加1到n;n个指令是移出数据。
现在要求移除数据的顺序为1到n。
为了满足最后输出的要求,小A可以在任何时候调整队列中数据的顺序。
请问 小A 最少需要调整几次才能够满足移除数据的顺序正好是1到n。
输入描述
第一行一个数据n,表示数据的范围。
接下来的2n行,其中有n行为添加数据,指令为:
- head add x表示从头部添加数据 x,
- tail add x 表示从尾部添加数据x,
另外 n 行为移出数据指令,指令为:remove 的形式,表示移出1个数据;
1 ≤ n ≤ 3 * 10^5。
所有的数据均合法
输出描述
一个整数,表示 小A 要调整的最小次数。
示例1
输入
5
head add 1
tail add 2
remove
head add 3
tail add 4
head add 5
remove
remove
remove
remove
输出
1
题解
思路:贪心
- 做这道题首先要想清楚两个问题:
- 什么时候队列中会乱序?
存在head add并且队列中已经存在元素时会导致队列乱序。因为1-n是按照顺序进行添加的,并且移除操作只会从头部移除元素,要保证顺序。 - 什么时候调整顺序最好? 在移除的元素的时候,队列为乱序时调整时是最好,这样可以做到
多次head add导致的乱序,一次调整好。
- 什么时候队列中会乱序?
- 想明白1的两个问题接下来就是进行模拟操作就行,使用
count记录现在队列中拥有的元素,使用is_order记录当前队列是否有序, 使用res记录操作次数。- 初始设置
count = 0, is_order = true. - 当进行插入
head add操作时,并且count > 0说明队列会变成乱序,变更is_order = false.并且count++ - 当进行
tail add增加队列拥有的数量。 - 当进行
remove操作时,如果is_order = false此时需要进行一次排序操作,res++并且变更is_false = true。 不管是否有序都要移除一个元素记录count--
- 初始设置
- 重复模拟2的操作,最终得到的
res就是结果。
c++
#include<iostream>
#include<vector>
#include<string>
#include <utility>
#include <sstream>
#include<algorithm>
#include<queue>
using namespace std;
int main() {
int n;
cin >> n;
int res = 0;
//去除换行符
string s;
getline(cin, s);
bool is_order = true;
int count = 0;
for (int i = 0; i < 2 * n; i++) {
getline(cin, s);
if (s.find("remove") != -1) {
// 只在移除的时候进行调整
if (!is_order) {
res++;
}
is_order = true;
count--;
} else if (s.find("tail") != -1) {
count++;
} else {
// 添加在头部会导致移除时乱序
if (count) {
is_order = false;
}
count++;
}
}
cout << res;
return 0;
}
C语言
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
int main() {
int n;
scanf("%d", &n);
int res = 0;
char s[100]; // 存储每行输入命令
fgets(s, sizeof(s), stdin); // 读取掉上一行的换行符
bool is_order = true; // 当前队列是否保持顺序
int count = 0; // 当前队列元素个数
// 总共有 2n 条指令
for (int i = 0; i < 2 * n; i++) {
if (fgets(s, sizeof(s), stdin) == NULL) break;
// 判断是否包含 remove
if (strstr(s, "remove") != NULL) {
// 只在移除的时候进行调整
if (!is_order) {
res++;
}
is_order = true;
count--;
}
// 判断是否包含 tail
else if (strstr(s, "tail") != NULL) {
count++;
}
// 否则是头部插入(例如 add head)
else {
// 添加在头部会导致移除时乱序
if (count > 0) {
is_order = false;
}
count++;
}
}
printf("%d\n", res);
return 0;
}
Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(); // 读取整数 n
scanner.nextLine(); // 处理换行符
int res = 0;
boolean isOrder = true;
int count = 0;
for (int i = 0; i < 2 * n; i++) {
String s = scanner.nextLine(); // 读取一行输入
if (s.contains("remove")) {
// 只在移除的时候进行调整
if (!isOrder) {
res++;
}
isOrder = true;
count--;
} else if (s.contains("tail")) {
count++;
} else {
// 添加在头部会导致移除时乱序
if (count > 0) {
isOrder = false;
}
count++;
}
}
System.out.println(res);
scanner.close();
}
}
Python
import sys
def main():
n = int(sys.stdin.readline().strip()) # 读取整数 n
res = 0
is_order = True
count = 0
for _ in range(2 * n):
s = sys.stdin.readline().strip() # 读取一行输入
if "remove" in s:
# 只在移除的时候进行调整
if not is_order:
res += 1
is_order = True
count -= 1
elif "tail" in s:
count += 1
else:
# 添加在头部会导致移除时乱序
if count > 0:
is_order = False
count += 1
print(res)
if __name__ == "__main__":
main()
JavaScript
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let input = [];
rl.on('line', (line) => {
input.push(line.trim());
if (input.length === 2 * parseInt(input[0]) + 1) {
let n = parseInt(input[0]);
let res = 0;
let isOrder = true;
let count = 0;
for (let i = 1; i <= 2 * n; i++) {
let s = input[i];
if (s.includes("remove")) {
// 只在移除的时候进行调整
if (!isOrder) {
res++;
}
isOrder = true;
count--;
} else if (s.includes("tail")) {
count++;
} else {
// 添加在头部会导致移除时乱序
if (count > 0) {
isOrder = false;
}
count++;
}
}
console.log(res);
rl.close();
}
});
Go
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
// 读取输入
reader := bufio.NewReader(os.Stdin)
var n int
fmt.Scan(&n) // 读取整数 n
res := 0
isOrder := true
count := 0
// 读取 2n 行指令
for i := 0; i < 2*n; i++ {
s, _ := reader.ReadString('\n')
s = strings.TrimSpace(s)
if strings.Contains(s, "remove") {
// 只在移除的时候进行调整
if !isOrder {
res++
}
isOrder = true
count--
} else if strings.Contains(s, "tail") {
count++
} else {
// 添加在头部会导致移除时乱序
if count > 0 {
isOrder = false
}
count++
}
}
fmt.Println(res)
}
浙公网安备 33010602011771号