CSP 201412-1 门禁系统
问题背景
涛涛负责图书馆管理工作,需要记录每天读者的到访情况。每位读者有一个编号,每条记录用读者的编号来表示。给出读者的来访记录,请问每一条记录中的读者是第几次出现。
输入输出说明
输入格式 第一行包含一个整数 n,表示记录条数。 第二行包含 n 个整数,依次表示每位读者的编号。
输出格式 输出一行,包含 n 个整数,由空格分隔,依次表示每条记录中的读者编号是第几次出现。
样例
输入:
5
1 2 1 1 3
输出:
1 1 2 3 1
解题思路
这道题的核心在于统计每个数字在当前位置之前(含当前位置)出现的次数。
虽然可以使用哈希表来优化到 O(n) 的时间复杂度,但考虑到题目约束 n ≤ 1000,直接使用双重循环暴力枚举也是完全可行的。这种方法逻辑直观,代码实现简单,非常适合初学者理解计数过程。
具体做法是遍历数组,对于每一个位置 j,向前扫描所有 i ≤ j 的位置,如果 s1[i] == s1[j],则计数器加一。这样就能准确得到该编号当前的出现次序。
代码实现
下面是具体的 C++ 实现方案。为了保持代码简洁且符合规范,我清理了部分冗余头文件和未使用的函数,并增加了必要的注释。
#include <iostream>
#include <cstring> // 使用 memset 需要此头文件
using namespace std;
const int MAXN = 1005;
int s1[MAXN], s2[MAXN];
int main() {
// 初始化数组,防止全局变量或内存中的垃圾值干扰
memset(s1, 0, sizeof(s1));
memset(s2, 0, sizeof(s2));
int n;
if (scanf("%d", &n) != 1) return 0;
// 读取所有来访记录
for (int i = 0; i < n; i++) {
(, &s1[i]);
}
( i = ; i < n; i++) {
( j = i; j < n; j++) {
(s1[i] == s1[j]) {
s2[j]++;
}
}
}
( i = ; i < n; i++) {
(, s2[i]);
}
;
}

