1 条题解

  • 0
    @ 2026-6-19 10:30:52

    📝 题目大意

    NN 个牙洞,每个牙洞初始有一颗牙齿。进行 QQ 次操作,每次指定一个牙洞 TiT_i:若该牙洞有牙齿则拔掉,无牙齿则种上。求最终剩余的牙齿数量。

    💡 解题思路

    1. 题目分析N,Q1000N, Q \le 1000,数据范围很小,直接模拟即可。问题本质是:初始全为 11(有牙齿),每次操作对指定位置进行翻转(101 \to 0010 \to 1)。
    2. 算法推导
      • 用一个数组 x(下标 1N1 \sim N)记录每个牙洞是否有牙齿,初始全为 11
      • 遍历 QQ 次操作,每次读入 aa(牙洞编号),将 x[a] 翻转:x[a] = 1 - x[a](或条件判断 1→0 / 0→1)。
      • 最后遍历数组统计 x[i] == 1 的个数,即剩余牙齿数。
    3. 边界与细节
      • 同一个牙洞可能被反复操作(如样例 2),翻转操作保证正确性。
      • 数组大小应开 N+1N+1 以避免越界,下标从 11 开始。
      • 最终结果最小为 00(所有牙齿被拔掉),最大为 NN(全部保留或种回)。

    ⏱️ 复杂度分析

    • 时间复杂度O(N+Q)O(N + Q),一次遍历初始化 + QQ 次操作 + 一次遍历统计。
    • 空间复杂度O(N)O(N),仅需一个长度为 N+1N+1 的数组。

    💻 标准代码 (C++)

    #include <bits/stdc++.h>
    using namespace std;
    int main(){
    	int n, q, c = 0, a;
    	cin >> n >> q;
    	int x[n + 1] = {};           // 数组 x 记录每个牙洞是否有牙齿
    	for (int i = 1; i <= n; i++) x[i] = 1; // 初始所有牙洞都有牙齿
    	for (int i = 1; i <= q; i++){
    		cin >> a;
    		// 翻转牙洞 a 的状态:有牙变无牙,无牙变有牙
    		if (x[a] == 1) x[a] = 0;
    		else x[a] = 1;
    	}
    	for (int i = 1; i <= n; i++){
    		if (x[i] == 1) c++;      // 统计剩余的牙齿数量
    	}
    	cout << c;
    }
    
    • 1

    信息

    ID
    788
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者