解题思路

  1. 题目要求对长度为 的序列进行 次操作,每次将选中的数字 移到序列最前面
  2. 关键点是要从后往前处理输入的操作序列,并用一个 visited 数组记录已经输出的数字
  3. 最后需要按顺序输出剩余未被访问过的数字
  4. 本质上是一个模拟题,需要注意处理顺序

代码

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    
    vector<bool> visited(n + 1, false);
    vector<int> operations(m);
    
    // 读入操作序列
    for(int i = 0; i < m; i++) {
        cin >> operations[i];
    }
    
    // 从后向前处理操作
    for(int i = m - 1; i >= 0; i--) {
        if(!visited[operations[i]]) {
            cout << operations[i] << endl;
            visited[operations[i]] = true;
        }
    }
    
    // 输出剩余未访问的数字
    for(int i = 1; i <= n; i++) {
        if(!visited[i]) {
            cout << i << endl;
        }
    }
    
    return 0;
}
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        
        boolean[] visited = new boolean[n + 1];
        int[] operations = new int[m];
        
        // 读入操作序列
        for(int i = 0; i < m; i++) {
            operations[i] = sc.nextInt();
        }
        
        // 从后向前处理操作
        for(int i = m - 1; i >= 0; i--) {
            if(!visited[operations[i]]) {
                System.out.println(operations[i]);
                visited[operations[i]] = true;
            }
        }
        
        // 输出剩余未访问的数字
        for(int i = 1; i <= n; i++) {
            if(!visited[i]) {
                System.out.println(i);
            }
        }
    }
}
n, m = map(int, input().split())
visited = [False] * (n + 1)
operations = []

# 读入操作序列
for _ in range(m):
    operations.append(int(input()))

# 从后向前处理操作
for i in range(m-1, -1, -1):
    if not visited[operations[i]]:
        print(operations[i])
        visited[operations[i]] = True

# 输出剩余未访问的数字
for i in range(1, n + 1):
    if not visited[i]:
        print(i)

算法及复杂度

  • 算法:模拟 + 哈希表(visited数组)
  • 时间复杂度: - 需要遍历一次操作序列和剩余数字
  • 空间复杂度: - 需要一个visited数组记录访问状态