华为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

题解

思路:贪心

  1. 做这道题首先要想清楚两个问题:
    1. 什么时候队列中会乱序? 存在head add 并且队列中已经存在元素时会导致队列乱序。因为1-n是按照顺序进行添加的,并且移除操作只会从头部移除元素,要保证顺序。
    2. 什么时候调整顺序最好? 在移除的元素的时候,队列为乱序时调整时是最好,这样可以做到多次head add导致的乱序,一次调整好。
  2. 想明白1的两个问题接下来就是进行模拟操作就行,使用count记录现在队列中拥有的元素,使用is_order记录当前队列是否有序, 使用res记录操作次数。
    1. 初始设置count = 0, is_order = true.
    2. 当进行插入head add 操作时,并且count > 0说明队列会变成乱序,变更is_order = false.并且count++
    3. 当进行tail add 增加队列拥有的数量。
    4. 当进行remove操作时,如果is_order = false此时需要进行一次排序操作,res++并且变更is_false = true。 不管是否有序都要移除一个元素记录count--
  3. 重复模拟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)
}
posted @ 2025-10-23 20:00  ycfenxi  阅读(7)  评论(0)    收藏  举报