- 智程星周赛
【ZCX-004-DIV3】智程星周赛004(入门组)
- @ 2026-4-15 10:49:52
题目思路
本题按照规则分三步:
1. 判断是否有重复
如果 a、b、c 中有任意两个相同,直接输出:
Report
2. 如果没有重复,优先选 d
如果 d 等于某个选项:
- d == a → 输出 A
- d == b → 输出 B
- d == c → 输出 C
3. 如果 d 不在选项中
选择三个数中的 第二大(中位数)
判断方法:
a 是中位数 ⇔ (a > b 且 a < c) 或 (a < b 且 a > c)
参考代码(带注释)
#include<bits/stdc++.h>
using namespace std;
int main(){
int a, b, c, d;
cin >> a >> b >> c >> d;
// ① 判重
if(a == b || b == c || a == c){
cout << "Report";
}
else{
// ② d 在选项中
if(a == d){
cout << "A";
}
else if(b == d){
cout << "B";
}
else if(c == d){
cout << "C";
}
else{
// ③ 找中位数
if((a > b && a < c) || (a < b && a > c)){
cout << "A";
}
else if((b > a && b < c) || (b < a && b > c)){
cout << "B";
}
else{
cout << "C";
}
}
}
return 0;
}
题目思路
本题是一个简单的顺序扫描问题。
做法:
从左到右遍历数组:
- 如果当前元素等于 x,则计数 cnt++
- 当 cnt == k 时,当前下标就是答案
- 如果遍历结束仍不足 k 次,输出 Error
关键点
- 下标从 1 开始
- 找到第 k 次后立即结束
- 不需要额外数据结构
参考代码(带注释)
#include<bits/stdc++.h>
using namespace std;
int a[100010];
int main(){
int n;
cin >> n;
// 输入数组
for(int i = 1; i <= n; i++){
cin >> a[i];
}
int k, x;
cin >> k >> x;
int cnt = 0; // 记录出现次数
// 遍历数组
for(int i = 1; i <= n; i++){
if(a[i] == x){
cnt++;
// 找到第 k 次
if(cnt == k){
cout << i;
return 0;
}
}
}
// 不足 k 次
cout << "Error";
return 0;
}
题目思路
对于每次询问给定一个 m,需要统计:
所有 a[i] % m 的结果中,有多少个不同的值。
做法(模拟)
对于每个询问:
- 遍历数组,计算每个 a[j] % m
- 用一个数组 T 记录某个余数是否出现过
- 再遍历 T,统计有多少个不同余数
- 最后清空 T,方便下一次询问使用
关键点
- 余数范围是 0 ~ m-1
- 用数组模拟“去重”
- 每次查询后要清空数组
复杂度分析
时间复杂度:O(n × q)
最大约 3000 × 1000 = 3e6,可以通过
空间复杂度:O(m)
参考代码(带注释)
#include<bits/stdc++.h>
using namespace std;
int a[3010], T[3010];
int main(){
int n, q;
cin >> n >> q;
// 输入数组
for(int i = 1; i <= n; i++){
cin >> a[i];
}
// 处理每个询问
for(int i = 1; i <= q; i++){
int m;
cin >> m;
// 统计余数出现情况
for(int j = 1; j <= n; j++){
T[a[j] % m]++;
}
int cnt = 0;
// 统计不同余数个数
for(int j = 0; j < m; j++){
if(T[j]){
cnt++;
}
T[j] = 0; // 清空,方便下一次查询
}
cout << cnt << endl;
}
return 0;
}
题目思路
给定两个数组 a 和 b,以及一个嵌套表达式,例如:
a[a[b[4]]]
要求计算该表达式的值。
核心思路
表达式计算顺序是 从内到外:
例如:
a[a[b[4]]]
计算顺序为:
- b[4]
- a[b[4]]
- a[a[b[4]]]
做法
1. 解析表达式
遍历字符串:
- 遇到 'a' → 记录操作 1
- 遇到 'b' → 记录操作 2
- 遇到数字 → 解析出最终的初始值 num
例如:
a[a[b[15]]]
解析为:
- 操作序列:a, a, b
- 初始值:15
2. 倒序执行操作
因为表达式是从内往外算,所以操作需要倒序执行:
b → a → a
依次更新 num。
复杂度分析
时间复杂度:O(m)
空间复杂度:O(m)
参考代码(带注释)
#include<bits/stdc++.h>
using namespace std;
int a[100010], b[100010], c[100010];
int main(){
int n;
cin >> n;
// 输入数组 a
for(int i = 1; i <= n; i++){
cin >> a[i];
}
// 输入数组 b
for(int i = 1; i <= n; i++){
cin >> b[i];
}
string s;
cin >> s;
int cnt = 0;
int num = 0;
// 解析表达式
for(int i = 0; i < s.size(); i++){
if(s[i] == 'a'){
c[++cnt] = 1;
}
else if(s[i] == 'b'){
c[++cnt] = 2;
}
else if(s[i] >= '0' && s[i] <= '9'){
num = num * 10 + s[i] - '0';
}
}
// 倒序执行操作
for(int i = cnt; i >= 1; i--){
if(c[i] == 1){
num = a[num];
}else{
num = b[num];
}
}
cout << num;
return 0;
}
总结
本题关键在于:
- 提取操作序列
- 提取初始数字
- 倒序执行数组访问
0 条评论
目前还没有评论...