• 第十二届蓝桥杯大赛模拟赛(第四期)


    博主没有参加模拟赛,题面来自网络,格式可能有些小问题,请见谅。

    第一题

    问题描述

      请问在 1900 到 2020 中,有多少个质数。

    答案:16

    暴力写即可

    第二题

    答案:P

    cout << (char)(80 - 65 + 'A');

    第三题

    答案:4041

    记度为0点为 x0, 度为1点为x1, 度为2点为x2

    x0=x2+1,当树节点个数为奇数时,1度点为0,否则为1,最少2021+2020=4041

    一段时间没看二叉树都快忘记节点数关系了...

    第四题

    答案:25

    很熟悉的一道题,类似题型:Here ABC181 D题.

    每个值对 3 取模

    void solve() {
        int cnt = 0, f[110] = {0, 1, 1};
        for (int i = 3; i <= 100; ++i) {
            f[i] = (f[i - 1] + f[i - 2]) % 3;
            if (f[i] % 3 == 0) cnt++;
        }
        cout << cnt;
    }
    

    第五题

    问题描述

      一个身份证号码有 18 位数字或字母组成。其中前17位必须是数字,最后一位可能是数字或字母X。
      身份证号码满足一定的校验规则。
      令身份证号从右到左依次标号为 1 到 18,其中标号为 i 的位的位权设置为 (2^{(i-1)} mod 11) (2的 (i-1) 次方除以 11 的余数)。
      将每一位的数值乘以位权后相加,得到的结果除以 11 的余数应当为 1。其中最后一位(标号为1)中如果出现字母 X,看成数字 10。
      例如,如果一个人的身份证号为 34052419800101001X,则:
      标号为 1 的位,位权 1,数值 X,即 10,相乘得 10。
      标号为 2 的位,位权 2,数值 1,相乘得 10。
      标号为 3 的位,位权 4,数值 0,相乘得 0。
      标号为 4 的位,位权 8,数值 0,相乘得 0。
      标号为 5 的位,位权 5,数值 1,相乘得 5。
      标号为 6 的位,位权 10,数值 0,相乘得 0。
      标号为 7 的位,位权 9,数值 1,相乘得 9。
      标号为 8 的位,位权 7,数值 0,相乘得 0。
      标号为 9 的位,位权 3,数值 0,相乘得 0。
      标号为 10 的位,位权 6,数值 8,相乘得 48。
      标号为 11 的位,位权 1,数值 9,相乘得 9。
      标号为 12 的位,位权 2,数值 1,相乘得 2。
      标号为 13 的位,位权 4,数值 4,相乘得 16。
      标号为 14 的位,位权 8,数值 2,相乘得 16。
      标号为 15 的位,位权 5,数值 5,相乘得 25。
      标号为 16 的位,位权 10,数值 0,相乘得 0。
      标号为 17 的位,位权 9,数值 4,相乘得 36。
      标号为 18 的位,位权 7,数值 3,相乘得 21。
      将乘积相加,得 199,除以 11 的余数正好为 1。
      小明的身份证号前 17 位为 11010120210221999,请问小明身份证的最后一位是多少?

    答案提交

      这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个字符,可能是数字或者大写字母X,在提交答案时只填写这个字符,填写多余的内容将无法得分。

    答案:8

    模拟,计算过程 mod 11

    qpow 的时候要用 n - i - 1 倒过来

    const int mod = 11;
    int qpow(int a, int b) {
        int ans = 1;
        for (; b; b >>= 1, a = a * a % mod)
            if (b & 1) ans = ans * a % mod;
        return ans;
    }
    void solve() {
        string s = "11010120210221999";
        int n = s.size(), cnt = 0;
        for (int i = 0; i < n; ++i)
            cnt = (cnt + (s[i] - '0') * qpow(2, n - i + 1)) % mod;
    
        cout << cnt % mod;
    }
    

    第六题

    小Hi的公司经常举办回馈社会的爱心活动。这次小Hi作为志愿者带领社区的孩子们参观了青少年天文馆。他发现孩子们对于摩尔斯电码非常感兴趣。

    摩尔斯电码由两种基本的信号组成:短信号"滴"(用字符'.'表示)以及长信号"嗒"(用字符'-'表示)。下图是数字0-9的摩尔斯电码表示,每个数字都由5个字符组成:

    .---- ..--- ...-- ....- ..... -.... --... ---.. ----. -----
    1     2     3     4     5     6     7     8     9     0
    

    为了让孩子们开心,小Hi决定把每位孩子的生日日期转化为摩尔斯码赠送给他们。例如日期20210101对应的摩尔斯电码是:

    ..--- ----- ..--- .---- ----- .---- ----- .----
    

    你能写一个程序帮助小Hi吗?

    输入格式

    第一行是一个整数N,代表参加活动的孩子的人数。(1 <= N <= 100)

    以下N行每行一个由0-9组成的字符串,代表一个生日日期。(日期格式:yyyymmdd,日期范围: 20000101至20210101)

    输出格式

    对于每个生日日期,输出一行表示转化后的摩尔斯码,数字之间用一个空格隔开。

    样例输入

    2  
    20161011  
    20000101
    

    样例输出

    ..--- ----- .---- -.... .---- ----- .---- .----
    ..--- ----- ----- ----- ----- .---- ----- .----
    
    map<int, string> mp;
    void solve() {
        mp.insert({1, ".----"});
        mp.insert({2, "..---"});
        mp.insert({3, "...--"});
        mp.insert({4, "....-"});
        mp.insert({5, "....."});
        mp.insert({6, "-...."});
        mp.insert({7, "--..."});
        mp.insert({8, "---.."});
        mp.insert({9, "----."});
        mp.insert({0, "-----"});
        string s;
        cin >> s;
        for (int i = 0, x; i < s.size(); ++i) {
            x = s[i] - '0';
            cout << mp[x] << " ";
        }
        cout << "
    ";
    }
    

    第七题

    问题描述

      给定一个单词,请将这个单词的首字母大写,后面的所有字母小写。

    输入格式

      输入一行包含一个字符串,表示给定的单词。

    输出格式

      输出变换后的单词。

    样例输入

    hello
    

    样例输出

    Hello
    

    样例输入

    WORLD
    

    样例输出

    World
    

    样例输入

    LanQiao
    

    样例输出

    Lanqiao
    

    数据规模和约定

      对于所有评测用例,单词的长度不超过 100,单词中只包含大小写英文字母。

    判断一下是否首位和大小写

    void solve() {
        string s;
        cin >> s;
        for (int i = 0; i < s.size(); ++i) {
            if (i == 0 && s[i] >= 'a' && s[i] <= 'z') s[i] = s[i] - 'a' + 'A';
            else if (i != 0 && s[i] >= 'A' && s[i] <= 'Z')
                s[i] = s[i] - 'A' + 'a';
        }
        cout << s;
    }
    

    第八题

    问题描述

      给定一个序列 S = (s[1], s[2], ..., s[n]),一个位置 p 上的变化度是指以这个位置为中心的相邻的 5 个元素的最大值与最小值的差,即 s[p-2], s[p-1], s[p], s[p+1], s[p+2] 中最大值与最小值的差。
      一个序列总共有 n-4 个变化度,位置 1, 2, n-1, n 没有变化度。
      例如,对于下面的序列 (1, 0, 4, 8, 5, 7, 6),总共有 3, 4, 5 三个位置有变化度,分别为 8, 8, 4。
      给定一个序列,请求出这个序列的变化度。

    输入格式

      输入的第一行包含一个整数 n,表示给定的序列长度。
      第二行包含 n 个整数 s[1], s[2], ..., s[n],表示给定的序列。

    输出格式

      输出一行,包含 n-4 个非负整数,分别表示每个位置的变化度。

    样例输入

    7
    1 0 4 8 5 7 6
    

    样例输出

    8 8 4
    

    数据规模和约定

      对于所有评测用例,(5 <= n <= 1000)(0 <= s[i] <= 1000000)

    这种题。。。

    直接暴力不可以?数据范围太小了

    代码就不写了

    第九题

    问题描述

      小Hi正在研究一种特殊的栈。这种栈的元素既可以从栈顶出栈,也可以从栈底出栈。(进栈还是只能从栈顶进栈)
      已知入栈的序列是1~N的一个排列,请你判断出栈序列能否是1, 2, 3, ... N?

    输入格式

      输入包含多组数据。
      输入第一行包含一个整数T,代表测试数据的组数。
      以下每组数据占据2行。
      第一行包含一个整数N。
      第二行包含N个整数,整数中由空格隔开。表示入栈序列。

    输出格式

      对于每组数据输出YES或者NO,代表出栈序列能否是1, 2, 3, ... N。

    样例输入

    2
    5
    2 4 1 3 5
    5
    4 3 1 5 2
    

    样例输出

    YES
    NO
    

    数据规模和约定

      对于30%的评测用例,(1 <= N <= 10)
      对于80%的评测用例,(1 <= N <= 10000)
      对于所有评测用例,(1 <= N <= 100000, 1 <= T <= 10)

    简单套用一下 deque,压队列的时候判断一下是否符合,然后先判断前面然后判断后面最后重新判断一下前面即可。

    • 时间复杂度:(mathcal{O}(n))
    // Murabito-B 21/04/16
    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    void solve() {
        int n;
        cin >> n;
        vector<int> a(n);
        for (int &x : a) cin >> x;
        deque<int> dq;
        int idx = 1;
        for (int i = 0; i < n; ++i) {
            dq.push_back(a[i]);
            if (a[i] == idx) idx++, dq.pop_back();
            while (!dq.empty() && dq.front() == idx)
                idx++, dq.pop_front();
            while (!dq.empty() && dq.back() == idx)
                idx++, dq.pop_back();
            while (!dq.empty() && dq.front() == idx)
                idx++, dq.pop_front();
        }
        cout << (idx == n + 1 ? "YES
    " : "NO
    ");
    }
    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        int _;
        for (cin >> _; _--;) solve();
        return 0;
    }
    

    第十题

    问题描述

      给定两个序列 (A=(a_1, a_2, ..., a_n))(B=(b_1, b_2, ..., b_m),) 它们的一个公共子序列是指从两个序列中分别取出相同个数的元素,按照原来的顺序排列后,对应位置的数值相等。
      例如,对于序列 A=(3, 2, 7, 6, 7) 和 B=(2, 3, 5, 7),可以在序列 A 中取出第 2, 3 个元素,在序列 B 中取出第 1, 4 个元素,值都是 2, 7,因此 2, 7 是一个公共子序列,在 A 中取第 2, 3 个元素和在 B 中取 1, 4 个元素是这个公共子序列的一种取法。
      在这两个序列中,有 4 中取法可以取出长度为 2 的公共子序列,例如

      1. 在 A 中取第 1, 3 个元素,在 B 中取 2, 4 个元素;
      2. 在 A 中取第 1, 5 个元素,在 B 中取 2, 4 个元素;
      3. 在 A 中取第 2, 3 个元素,在 B 中取 1, 4 个元素;
      4. 在 A 中取第 2, 5 个元素,在 B 中取 1, 4 个元素。
    给定两个序列,请问有多少种取法可以取出长度为 k 的公共子序列。

    输入格式

      输入第一行包含三个整数 n, m, k,分别表示序列 A 的长度、序列 B 的长度和公共子序列的长度。
      第二行包含 n 个整数 (a_1, a_2, ..., a_n),表示给定的 A 序列。
      第三行包含 m 个整数 (b_1, b_2, ..., b_m),表示给定的 B 序列。

    输出格式

      输出一行,包含一个整数,表示长度为 k 的公共子序列的数量,答案可能很大,请输出答案除以 1000007 的余数。

    样例输入

    5 4 2
    3 2 7 6 7
    2 3 5 7
    

    样例输出

    4
    

    数据规模和约定

      对于 30% 的评测用例,(1 <= n, m <= 20)
      对于 50% 的评测用例,(1 <= n, m <= 100)
      对于所有评测用例,(1 <= n, m <= 1000, 1 <= k <= 10, 0 <= a_i <= 100)

    LCS 变形

    初始化:每个 (dp(i,j,0) = 1)

    状态转移方程

    [dp[i,j,k] += dp[i - 1,j,k] + d[i,j - 1,k]\ if:a[i] = b[j],dp[i][j][k] += dp[i - 1][j - 1][k - 1] - dp[i - 1][j - 1][k], dp[i][j][k]\ else:dp[i][j][k] -= dp[i - 1][j - 1][k], dp[i][j][k] ]

    // Murabito-B 21/04/16
    #include <bits/stdc++.h>
    using namespace std;
    using ll    = long long;
    const int N = 1100, mod = 1000007;
    ll dp[N][N][11], f[N][N];
    void solve() {
        int n, m, K;
        cin >> n >> m >> K;
        vector<int> a(n + 1), b(m + 1);
        for (int i = 1; i <= n; ++i) cin >> a[i];
        for (int i = 1; i <= m; ++i) cin >> b[i];
        for (int i = 0; i <= n; ++i)
            for (int j = 0; j <= m; ++j) dp[i][j][0] = 1;
    
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= m; ++j) {
                if (a[i] == b[j]) f[i][j] = max(f[i - 1][j - 1] + 1, f[i][j]);
                else
                    f[i][j] = max(f[i - 1][j], f[i][j - 1]);
            }
    
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                for (int k = 1; k <= K; k++) {
                    dp[i][j][k] += dp[i][j - 1][k], dp[i][j][k] %= mod;
                    dp[i][j][k] += dp[i - 1][j][k], dp[i][j][k] %= mod;
                    if (a[i] == b[j]) dp[i][j][k] += dp[i - 1][j - 1][k - 1] - dp[i - 1][j - 1][k], dp[i][j][k] %= mod;
                    else
                        dp[i][j][k] -= dp[i - 1][j - 1][k], dp[i][j][k] %= mod;
                }
            }
        }
        cout << dp[n][m][K] << "
    ";
    }
    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        solve();
        return 0;
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    017 文件xfs_repair恢复,xfs_dump恢复,lvm动态扩容
    003 rsync客户端与服务端小脚本
    002 rsync守护进程传输方式详解
    001 期中架构简介、备份初识
    016 netstat、磁盘分区(fdisk、gdisk)
    015 Linux中常用的信号、HUP信号
    014 进程(PS与TOP)
    013 源码安装(Nginx&php为例)
    本地、远程仓库的搭建
    第八章
  • 原文地址:https://www.cnblogs.com/RioTian/p/14668487.html
Copyright © 2020-2023  润新知