题目思路

本题按照规则分三步:

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;
}

题目思路

本题是一个简单的顺序扫描问题。

做法:

从左到右遍历数组:

  1. 如果当前元素等于 x,则计数 cnt++
  2. 当 cnt == k 时,当前下标就是答案
  3. 如果遍历结束仍不足 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 的结果中,有多少个不同的值。


做法(模拟)

对于每个询问:

  1. 遍历数组,计算每个 a[j] % m
  2. 用一个数组 T 记录某个余数是否出现过
  3. 再遍历 T,统计有多少个不同余数
  4. 最后清空 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]]]

计算顺序为:

  1. b[4]
  2. a[b[4]]
  3. 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 条评论

目前还没有评论...