B3842【春游】完整详细笔记
一、题目详细讲解
1. 题目大意
老师带学生春游,班上一共有 N 位同学。
每位同学拥有唯一编号:0 ~ N-1(重点必考)。
一共有M 次报号记录,到达的同学会报自己编号,允许重复报号。
题目要求:找出没有来过、从未报号的同学。
2. 输出规则(易错点)
① 如果存在未到同学:从小到大输出缺席编号;
② 如果全部同学都到场:不要输出编号,直接输出数字 N。
3. 数据范围
2 ≤ N,M ≤ 1000,数据很小,使用普通数组即可完成。
4. 样例解释
样例1:
输入:3 3 0 2 1
分析:编号0、1、2全部报号,全员到达,输出 3。
样例2:
输入:3 5 0 0 0 0 0
分析:只有0号报号,1、2从未报号,输出 1 2。
二、完整AC代码
三、逐行超详细讲解
1. 头文件与全局数组
(1) #include<bits/stdc++.h>:万能头文件,包含所有常用函数;
(2) int vis[1005]:标记数组(本题核心)。
✅ 全局数组默认初始值全部为 0;
✅ vis[x] = 0 代表 x号同学未到达;
✅ vis[x] = 1 代表 x号同学已到达。
2. main函数初始变量
① sum:专门统计缺席同学的人数,初始为0;
② n:全班总人数;
③ m:一共多少次报号;
④ cin读取第一行两个整数。
3. 第一层循环:标记到场同学
① 循环执行m次,对应m次报号;
② 每次读入一个编号x;
③ vis[x] = 1:把该同学标记为已经到达;
💡 重点:就算同一个人重复报号,反复赋值1,不会产生任何错误,自动去重。
4. 第二层循环:查找缺席同学
① 循环范围 i = 0 到 n-1,严格贴合题目编号规则;
② if(vis[i]==0):该编号从未被标记 = 没有来;
③ 直接输出编号,因为i从小到大遍历,输出天然升序;
④ sum++:每找到一个缺席同学,计数器加一。
5. 特殊判断:全员到场
① sum==0 代表:没有任何一个人缺席;
② 题目硬性规定:全员到达时,输出 n,不能输出0;
③ 这是本题最大易错点。
四、整体解题思路框架
步骤1:定义标记数组vis,初始全部为0,默认所有人未到;
步骤2:读取每一次报号,把报过号的人标记为1;
步骤3:从头到尾遍历所有同学编号,找出数值为0的人(缺席);
步骤4:统计缺席人数,如果无人缺席,输出n;
步骤5:程序结束。
五、易错坑点总结(考试必看)
❌ 坑点1:编号从1开始循环 → 正确:必须从0开始;
❌ 坑点2:全员到达输出0 → 正确:必须输出n;
❌ 坑点3:不会处理重复报号 → 正确:重复赋值1无需处理;
❌ 坑点4:输出顺序混乱 → 正确:正序遍历天然升序。
六、本题核心知识点
✅ 一维数组用法
✅ 标记思想(状态记录)
✅ 模拟题目逻辑
✅ 特殊条件判断