zoukankan      html  css  js  c++  java
  • 「CSP-S 2020」初赛解析

    • 前言

      upt2020/10/24:补上了代码。

      如何评价 Rainy7 白给 6 分。

      好丢人啊呜呜呜。

      主要参考:link。还有大佬同学的分析。(wtcl)

      注:由于Rainy7太菜,部分观点全靠口胡/胡扯/跳过。如果出现解释/知识错误,欢迎指出。


    • 选择题

    1.请选出以下最大的数

    A.((556)_{10})

    B.((777)_8)

    C.(2^{10})

    D.((22F)_{16})

    ((777)_8=551)

    (2^{10}=1024)

    ((22F)_{16}=559)

    故选 C 。

    2.操作系统的功能是()

    A.负责外设与主机之间的信息交换

    B.控制和管理计算杋系统的各种硬件和软件资源的使用

    C.负责诊断机器的故障

    D.将源程序编译成目标程序

    操作系统(Operating System,简称OS)是管理计算机硬件与软件资源的计算机程序。操作系统需要处理如管理与配置内存、决定系统资源供需的优先次序、控制输入设备与输出设备、操作网络与管理文件系统等基本事务。操作系统也提供一个让用户与系统交互的操作界面。 ——百度百科

    概念性知识点。选 B 。

    3.现有一段 (8) 分钟的视频文件,它的播放速度是每杪 (24) 帧图像,每帧图像是幅分辨率为 (2048 imes 1024) 像素的 (32) 位真彩色图像。请问要存储这段原始无压缩视频,需要多大的存储空间?

    A. 30G B. 90G C.150G D.450G

    一帧的空间为 (2048 imes 1024 imes 32) bit 。

    所以整个文件为总帧数的空间。

    [2048 imes 1024 imes 32 imes 8 imes 60 imes 24 (bit) ]

    [=90(GB) ]

    故选 B 。

    今有一空栈S,对下列待进栈的数据元素序列a,b,c,d,e,f依次进行:进栈,进栈,出栈,进栈,进栈,出栈的操作,则此操作完成后,栈底元素为

    A.b B.a C.d D.c

    栈内元素依次为 (a o a,b o a o a,c o a,c,d o a,c)

    选 B 。

    5.将(2,7,10,18)分别存储到某个地址区间为0~10的哈希表中,如果哈希函数h(x)=(),将不会产生冲突,其中 (a mod b) 表示 a 除以 b 的余数。

    A. (x^2 mod 11)

    B. (2x mod 11)

    C. (x mod 11)

    D.(leftlfloordfrac{x}{2} ight floor mod 11) ,其中 (leftlfloordfrac{x}{2} ight floor) 表示下取整

    A 中各个数为 (4,5,1,5)

    B 中各个数为 (4,3,9,3)

    C 中各个数为 (2,7,10,7)

    D 中各个数为 (1,3,5,9)

    故选 D 。

    6.下列哪些问题不能用贪心法精确求解?()

    A. 霍夫曼编码

    B. 0-1背包问题

    C. 最小生成树

    D. 单源最短路问题

    A 为贪心。 C 的 prim 和 kruskal 为贪心。 D 的 dijsktra 为贪心。

    故选 B 。

    7.具有η个顶点,e条边的图采用邻接表存储结构,进行深度优先遍历运算的时间复杂度为()。

    A. (O(n+e)) B.(O(n^2)) C.(O(e^2)) D.(O(n))

    每个点,跑所连的每一个边。一次。

    故选 A。

    8.二分图是指能将顶点划分成两个部分,每一部分内的顶点间没有边相连的简单无向图。那么,24个顶点的二分图至多有()条边

    A.144 B.19 C.48 D.122

    考虑最大情况,两边个数都为 (12)

    答案即 (12^2=144)

    故选 A 。

    9.广度优先搜索时,一定需要用到的数据结构是()

    A.栈

    B.二叉树

    C.队列

    D.哈希表

    选 C 。

    10.一个班学生分组做游戏,如果每组三人就多两人,每组五人就多三人,每组七人就多四人,问这个班的学生人数n在以下哪个区间?已知n<60。

    A.30<n<40

    B.40<n<50

    C.50<n<60

    D.20<n<30

    通过暴力,可得当 (n=53) 的时候满足。

    故选 C 。

    11.小眀想通过走楼梯来锻炼身体,假设从第 (1) 层走到第 (2) 层消耗 (10) 卡热量,接着从第 (2) 层走到第 (3) 层消耗 (20) 卡热量,再从第 (3) 层走到第 (4) 层消耗 (30) 卡热量,依此类推,从第 (k) 层走到第 (k+1) 层消耗 (10k) 卡热量 ((k>1)) 。如果小明想从 (1) 层开始,通过连续向上爬楼梯消耗 (1000) 卡热量,至少要爬到第几层楼?

    A.14 B.16 C.15 D.13

    设爬到 (x) 层。

    [10 imes (1+2+3+...+x-1) ge 1000 ]

    [x=15 ]

    故选 C 。

    12.表达式a*(b+c)-d的后缀表达形式为()

    A. abc*+d-

    B. -+*abcd

    C. abcd*+-

    D. abc+*d-

    各种方法都可以做出来,选 D 。

    1. 从一个4×4的棋盘中选取不在同一行也不在同一列上的两个方格,共有()种方法。

    A.68 B.72 C.86 D.64

    (16 imes 9 imes frac{1}{2}=72)

    故选 B 。

    14.对一个n个顶点、m条边的带权有向简单图用 Dijkstra算法计算单源最短路时,如果不使用堆或其它优先队列进行优化,则其时间复杂度为

    A. (O((m+n^2) log n))

    B. (O(mn+n^3))

    C. (O((m+n) log n))

    D. (0(n^2))

    没优化的 dijkstra ,每次枚举找 (n) 个点,枚举 (n) 次。

    故选 D。

    15.1948年,()将热力学中的熵引入信息通信领域,标志着信息论研究的开端。

    A.欧拉( Leonhard Euler)

    B.冯·诺伊曼(John von Neumann)

    C.克劳德·香农(Claude shannon)

    D.图灵(Alan turing)

    克劳德·艾尔伍德·香农(Claude Elwood Shannon ,1916年4月30日—2001年2月24日)是美国数学家、信息论的创始人。1936年获得密歇根大学学士学位 [1] 。1940年在麻省理工学院获得硕士和博士学位,1941年进入贝尔实验室工作。香农提出了信息熵的概念,为信息论和数字通信奠定了基础。 ——百度百科

    故选 C 。


    • 阅读程序

    所有程序题,包括完善程序,的程序会在网络上有可以复制版的时候搬过来。

    手写一遍?不可能((

    (1)

    #include <iostream>
    using namespace std;
    
    int n;
    int d[1000];
    
    int main() {
      cin >> n;
      for (int i = 0; i < n; ++i)
        cin >> d[i];
      int ans = -1;
      for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
          if (d[i] < d[j])
             ans = max(ans, d[i] + d[j] - (d[i] & d[j]));
        cout << ans;
        return 0;
    }
    

    1.n必须小于1000,否则程序可能会发生运行错误。()

    代码下标从 (0) 开始存,若 (n=1000) ,程序不会运行错误。

    故判错。

    1. 输出一定大于等于0。()

    看上去 ans 一定会大于等于 0 。

    但是 ans 初始为 (-1)

    当所有 (d[i]) 相等时,ans 不会改变。

    故判错。

    1. 若将第13行的j=0改为j=i+1,程序输出可能会改变。()

    若程序为严格单调递减,输出变为 (-1) 实际是有解的。

    故判对。

    1. 将第14行的d[i]<d[j]改为d[i]!=d[j],程序输出不会改变。()

    改完后, (d[i]>d[j]) 的情况也会执行。但是对结果没影响。

    故判对。

    5)若输入n为100,且输出为127,则输入的d[i]中不可能有()

    A. 127 B.126 C.128 D.125

    如果有比 (127) 大的,结果也一定比 127 大。

    所以选 C 。

    6)若输出的数大于,则下面说法正确的是()

    A.若输出为偶数,则输入的d[i]中最多有两个偶数。

    B.若输出为奇数,则输入的d[i]中至少有两个奇数。

    C.若输出为偶数,则输入的d[i]中至少有两个偶数。

    D.若输出为奇数,则输入的d[i]中最多有两个奇数。

    用奇偶性判断。

    首先 A 和 D 明显不对(……) 。

    如果两个数为偶数,与完还是偶数。

    如果两个数一奇一偶,与完是偶数。

    如果两个数为奇数,与完还是奇数。

    所以若结果为奇数,偶+奇+(偶&奇)=奇 ,也就是说 B 不对。

    看 C ,偶+偶+(偶&偶)=偶,奇+奇+(奇&奇)=奇。

    故选 C 。

    (2)

    #include <iostream>
    #include <cstdlib>
    using namespace std;
    
    int n;
    int d[10000];
    
    int find(int L, int R, int k) {
        int x = rand() % (R - L + 1) + L;
        swap(d[L], d[x]);
        int a = L + 1, b = R;
        while (a < b) {
            while (a < b && d[a] < d[L])
                ++a;
            while (a < b && d[b] >= d[L])
                --b;
            swap(d[a], d[b]);
        }
        if (d[a] < d[L])
            ++a;
        if (a - L == k)
            return d[L];
        if (a - L < k)
            return find(a, R, k - (a - L));
        return find(L + 1, a - 13, k);
    }
    
    int main() {
        int k;
        cin >> n;
        cin >> k;
        for (int i = 0; i < n; ++i)
            cin >> d[i];
        cout << find(0, n - 1, k);
        return 0;
    }             
    

    假设输入的n,k和都是不超过100的正整数,且k不超过n,并假设rand()函数产生的是均匀的随机数,完成下面的判断题和单选题:

    1. 第9行的x的数值范围是L+1到R,即[L+1,R]。()

    这题看上去很 nth_element

    如果正好随机到倍数,是可以取到 L 的。

    故判错。

    1. 将第19行的d[a]改为d[b],程序不会发生运行错误。()

    可以发现,无论如何 (a) 都不会越界。

    故判对。

    3.(2.5分)当输入的d[i]是严格单调递增序列时,第17行的swap平均执行次数是()。

    A.(O(n log n))

    B.(O(n))

    C.(O( log n))

    D.(O(n^2))

    官方:答案为 (O(( log n)^2)) ,无正确选项,因此无论选择哪个选项都算对。

    但是这个结果是怎么算的呢(……)

    4.(2.5分)当输入的d[i]是严格单调递减序列时,第17行的“swap”平均执行次数是()

    A. (O(n^2))

    B. (O(n))

    C. (O(n log n))

    D. (O( log n))

    (战术胡扯)

    大概随机选一个,随机选完两边的数都要两两交换,即 (O(n))

    但是往下已经交换,所以结果最后最多 (O(n))

    故选 B 。

    5.(2.5分)若输入的 (d[i])(i) ,此程序①平均的时间复杂度和②最坏情况下的时间复杂度分别是

    A. (O(n),O(n^2))

    B. (O(n),(n log n))

    C. (O(n log n),O(n^2))

    D. (O(n log n),O(n log n))

    平均复杂度 (O(n))

    以下 by @ifndef

    期望时间复杂度为 (T(n) = T(dfrac{n}{2}) + n = Theta(n))

    以下 by @Konnyaku_LXZ
    :

    最坏情况的时候,比如你真的太非了(雾),每次 rand() 出的 (x) 都是 (L),那么 (b) 会从 (R) 一直跑到 (L+1),时间复杂度就是 (T(n) = T(n-1) + n = Theta(n^2))

    故选 A 。

    6)(2.5分)若输入的d[i]都为同一个数,此程序平均的时间复杂度是

    A. (O(n))

    B. (O( log n))

    C. $O(n log n) $

    D. (O(n^2))

    随机了个寂寞。

    每次 (a) 不变,(b) 要从 (R) 跑到 (L) 。然后在跑子程序。

    所以结果为 (O(n^2))

    故选 D 。

    (3)

    #include <iostream>
    #include <queue>
    using namespace std;
    
    const int maxl = 20000000;
    
    class Map {
        struct item {
            string key; int value;
        } d[maxl];
        int cnt;
      public:
        int find(string x) {
            for (int i = 0; i < cnt; ++i)
                if (d[i].key == x)
                    return d[i].value;
            return -1;
        }
        static int end() { return -1; }
        void insert(string k, int v) {
            d[cnt].key = k; d[cnt++].value = v;
        }
    } s[2];
    
    class Queue {
        string q[maxl];
        int head, tail;
      public:
        void pop() { ++head; }
        string front() { return q[head + 1]; }
        bool empty() { return head == tail; }
        void push(string x) { q[++tail] = x;  }
    } q[2];
    
    string st0, st1;
    int m;
    
    string LtoR(string s, int L, int R) {
        string t = s;
        char tmp = t[L];
        for (int i = L; i < R; ++i)
            t[i] = t[i + 1];
        t[R] = tmp;
        return t;
    }
    
    string RtoL(string s, int L, int R) {
        string t = s;
        char tmp = t[R];
        for (int i = R; i > L; --i)
            t[i] = t[i - 1];
        t[L] = tmp;
        return t;
    }
    
    bool check(string st , int p, int step) {
        if (s[p].find(st) != s[p].end())
            return false;
        ++step;
        if (s[p ^ 1].find(st) == s[p].end()) {
            s[p].insert(st, step);
            q[p].push(st);
            return false;
        }
        cout << s[p ^ 1].find(st) + step << endl;
        return true;
    }
    
    int main() {
        cin >> st0 >> st1;
        int len = st0.length();
        if (len != st1.length()) {
            cout << -1 << endl;
            return 0;
        }
        if (st0 == st1) {
            cout << 0 << endl;
            return 0;
        }
        cin >> m;
        s[0].insert(st0, 0); s[1].insert(st1, 0);
        q[0].push(st0); q[1].push(st1);
        for (int p = 0;
                !(q[0].empty() && q[1].empty());
                p ^= 1) {
            string st = q[p].front(); q[p].pop();
            int step = s[p].find(st);
            if ((p == 0 &&
                    (check(LtoR(st, m, len - 1), p, step) ||
                     check(RtoL(st, 0, m), p, step)))
                    ||
                    (p == 1 &&
                     (check(LtoR(st, 0, m), p, step) ||
                      check(RtoL(st, m, len - 1), p, step))))
                return 0;
        }
        cout << -1 << endl;
        return 0;
    }
    

    这个程序手写了一些数据结构。

    每次操作旋转一段字符串([0,m]或[m,n])。问几次 (st0) 可以和 (st1) 相等。

    用的是双向搜索。

    1.输出可能为0。()

    (st0=st1) 会被程序特判为 (0)

    故判对。

    2.若输入的两个字符串长度均为101时,则m=0时的输出与m=100时的输出是一样的()

    一个像左,一个像右,故不一样。

    3.若两个字符串的长度均为n,则最坏情况下,此程序的时间复杂度为0(n!)。()

    最劣复杂度应该为 (O((n!)^2 ·n))

    4.(2.5分)若输入的第一个字符串长度由100个不同的字符构成,第个字符串是第一个字符串的倒序,输入的m为0,则输出为()

    A.49 B.50 C.100 D.-1

    手玩可得,不可能,故选 D 。

    5)(4分)已知当输入为0123 32 1时输出为4,当输入为812345 54321 1时输出为14,当输入为61234567 76543210 1时输出为28,则当输入为0123456789 9876543210 1输出为()。其中 为换行符。

    A.56 B.84 C.102 D.68

    RP game(雾

    以下直接摘自前言的link。

    容易构造一个比较劣的耗费 (mathcal{O}(n^2)) 步的操作序列,于是可以猜想当 (n) 足够大时答案为关于 (n) 的二次多项式,用给出的三个值进行插值即可得到答案为 (68)

    以下 by @chen_03

    发现字符串长度为 (4) 时答案为 (4) ,长度为 (6) 时答案为 (14) ,长度为 (8) 时答案为 (28) ,差分别为 (10,14) 。于是猜测接下来的两个差分别为 (18,22) ,于是长度为 (12) 时答案为 (28+18+22=68)

    故选 D 。

    1. (4分)若两个字符串的长度均为 (n) ,且 (0<m<n-1) ,且两个字符串的构成相同(即任何一个字符在两个字符串中出现的次数均相同),则下列说法正确的是()。提示:考虑输入与输出有多少对字符前后顺序不样

    A.若n、m均为奇数,则输出可能小于0。

    B.若n、m均为偶数,则输出可能小于0。

    C.若n为奇数、m为偶数,则输出可能小于0。

    D.若n为偶数、m为奇数,则输出可能小于0。

    小于 (0) 就是无解。

    C中,凑偶数,就有可能无法凑成奇数。

    故选 C 。


    • 完善程序

    1.(分数背包)小S有 (n) 块蛋糕,编号从 (1)(n) 。第 (i) 块蛋糕的价值是 (w) 体积是 (v) 。他有一个大小为 (B) 的盒子来装这些蛋糕,也就是说装入盒子的蛋糕的体积总和不能超过 (B)

    他打算选择一些蛋糕装入盒子,他希望盒子里装的蛋糕的价值之和尽量大。为了使盒子里的蛋糕价值之和更大,他可以任意切割蛋糕。具体来说,他可以选择一个 $ alpha (0< alpha <1) $,并将一块价值是 (w) ,体积为 (ⅴ) 的蛋糕切割成两块,其中一块的价值是 (alpha·w) ,体积是 $ alpha·v$ ,另一块的价值是 ((1-alpha)·w) ,体积是 ((1-alpha)·ⅴ)

    他可以重复无限次切割操作现要求编程输岀最大可能的价值,以分数的形式输出比如 (n=3,B=8) 三块蛋糕的价值分别是4、4、2,体积分别是5、3、2。那么最优的方案就是将体积为5的蛋糕切成两份,一份体积是3,价值是4,另一份体积是2,价值是1.6,然后把体积是3的那部分和后两块蛋糕打包进盒子。最优的价值之和是 (8.4) ,故程序输出 (42/5)

    输入的数据范围为: (1 le n le 1000,1 le B le 10^5;1 le frac{w_i}{v_i} le 100) 。提示:将所有的蛋糕按照性价比w/v从大到小排序后进行贪心选择。试补全程序。

    #include <cstdio>
    using namespace std;
    
    const int maxn = 1005;
    
    int n, B, w[maxn], v[maxn];
    
    int gcd(int u, int v) {
        if (v == 0)
            return u;
        return gcd(v, u % v);
    }
    
    void print(irrt w, int v) {
        int d = gcd(w, v);
        w = w / d;
        v = v / d;
        if (v == 1)
            printf("%d
    ", w);
        else
            printf("%d/%d
    " w, v);
    }
    void swap(int &x, int &y) {
        int t = x; x = y; y = t;
    }
    
    int main() {
        scanf("%d %d" &n, &B);
        for (int i = 1; i <= n; i ++) {
            scanf("%d %d", &w[i], &v[i]);
        }
        for (int i = 1; i < n; i ++)
            for (int j = 1; j < n; j ++)
                if (①) {
                    swap(w[j], w[j + 1]);
                    swap(v[j], v[j + 1]);
                }
        int curV, curW;
        if  (②) {
            ③
        } else {
            print(B * w[1] > v[1]);
            return 0;
        }
        for (int i = 2; i <= n; i ++)
            if (curV + v[i] <= B) {
                curV += v[i];
                curW += w[i];
            } else {
                print (④);
                return 0;
            }
        print(⑤);
        return 0;
    }
    

    1.①处应填().

    A. w[j]/v[j] < w[j+1] /v[j+1]

    B. w[j]/v[j] > w[j+1] /v[j+1]

    C. v[j] * w[j+1] < v[j+1] * w[j]

    D. w[j] * v[j+1] < w[j+1] * v[j]

    按照提示所说的排序。

    但是因为不是 double ,所以要转换为乘法。

    故选 D 。

    2.②中应填()

    A. w[1]<=B

    B. v[1]<=B

    C. w[1]>=B

    D. v[1]>=B

    else 反推,else 直接 return 0 +输出。说明是v[1]>B 的情况。故选 B 。

    3.③中应填()

    A. print(v[1],w[1]);return 0;

    B. curV=0;curW=0;

    C. print(w[1],v[1]);return 0;

    D. curV=v[1];curW=w[1];

    A 和 C 在干啥……

    注意到下面 for2 开始,故选 D。

    4.④中应填()

    A. curW * v[i]+curV[i] * w[i],v[i]

    B. (curW-w[i])*v[i]+(B-curV)*w[i],v[i]

    C. curW+v[i],w[i]

    D. curW*v[i]+(B-curV)*w[i],v[i]

    首先,排除 B 和 C 。

    (B-curV) 的目的是求这块蛋糕切成几分之几。

    curW*v[i] 是使这部分已经求好的整块蛋糕的价值和,即分子,和分母一起扩大。最后结果不受分母影响。

    (curW-w[i]) 意义不明(……?)

    故选 D 。

    5.⑤中应填()

    A. curW,curV

    B. curW,1

    C. curV,curW

    D. curV,1

    注意到此时没有任何蛋糕被切掉。

    所以分母为 (1)

    故选 B 。

    2.(最优子序列)取 (m=16) ,给出长度为 (n) 的整数序列 (a_1,a_2,...,a_n(0 le a_i < 2^m)) 。对于一个二进制数 (x) ,定义其分值 (w(x))(x+ popcnt(x)) ,其中$ popcnt(x)$ 表示 (x) 二进制表示中 (1) 的个数。对于一个子序列 (b_1,b_2,...,b_k,) 定义其子序列分值 (S)(w(b1 oplus b2)+w(b2 oplus b3)+W(b3 oplus b4)+ ... +w(b_{k-1} oplus b_k)) 。其中 (oplus) 表示按位异或。对于空子序列,规定其子序列分值为0。

    求一个子序列使得其子序列分值最大,输出这个最大值。

    输入第一行包含一个整数 (n(1 le n le 40000))。接下来一行包含 (n) 个整数 (a_1,a_2,...,a_n)

    提示:考虑优化朴素的动态规划算法,将前位和后位分开计算 (Max[x][y]) 表示当前的子序列下一个位置的高 (8)位是(x)、最后一个位置的低 (8) 位是 (y) 时的最大价值。

    #inelude <iostream>
    
    using namespace std;
    
    typedef long long LL;
    
    const int MAXN = 40000, M = 16, B = M >> 1, MS = (1 << B) - 1;
    const LL INF = 1000000000000000LL;
    LL Max[MS + 4][MS + 4];
    
    int w(int x) 
    {
        int s = x;
        while(x) 
        {
            ①;
            s++;
        }
        return s;
    }
    
    void to_max(LL &x, LL y) 
    {
        if(x < y)
            x = y;
    }
    
    int main() 
    {
        int n;
        LL ans = 0;
        cin >> n;
        for(int x = 0; x <= MS; x++)
            for(int y = 0; y <= MS; y++)
                Max[x][y] = -INF;
        for(int i = 1; i <= n ; i++) 
        {
            LL a;
            cin >> a;
            int x = ② , y = a & MS;
            LL v = ③;
            for(int z = 0; z < = MS; z++)
                to_max(v, ④);
            for(int z = 0; z < = MS; z++)
                ⑤;
            to_max(ans , v);
        }
        cout << ans << endl;
        return 0;
    }
    

    1.①处应填().

    A. x>>=1

    B. x^=x&(x^(x+1))

    C. x-=x|-x

    D. x^=x&(x^(x-1))

    lowbit

    可以手动尝试((,选 D 。

    2.②中应填()

    A. (a&MS)<<B

    B. a>>B

    C. a&(1<<B)

    D. a&(Ms<<B)

    第二题,根据题目中 (x) 的定义。

    那么 x 为 a 的 B 位的数。

    故选 B 。

    3.③中应填()

    A. -INF

    B. Max[y][x]

    C. 0

    D. Max[x][y]

    此时 Max 并未赋值。排除 B 和 D 。

    空串的值为 (0)

    故选 C 。

    4.④中应填()

    A. Max[x][z]+w(y^z)

    B. Max[x][z]+w(a^z)

    C. Max[x][z]+w(x^(z<<B))

    D. Max[x][z]+w(x^z)

    根据 (Max[x][z]) 可得,这次是在变换 (y)

    y^z 就是补充 z 剩下的 (1) 的贡献。

    故选 A 。

    5.⑤中应填()

    A. to_max(Max[y][z],v+w(a^(z<<B)))

    B. to_max(Max[z][y],v+w((x^z)<<B)

    C. to_max(Max[z][y],v+w(a^(z<<B)))

    D. to_max(Max[x][z],v+w(y^z))

    易得,这次是固定 (y) ,变换 (x)

    故排除 A 和 D 。

    变换 (x) 的值也时时更新。

    和上一题一样,x^z 是补充 z 剩下的 (1) 的贡献。

    再回题目看概念,下一个位置的高 (8) 位是(x)

    所以 (x) 需要恢复到高位的贡献,再与 (v) 相加。

    故选 B 。


    [ ext{by Rainy7} ]

  • 相关阅读:
    第十一章关联容器
    第十章泛型算法
    第九章
    第八章
    阅读记录
    java.lang.Class阅读笔记
    java.time包阅读笔记
    CLion运行多个main函数
    c++中lower_bound和upper_bound中的comp参数
    如何写dfs
  • 原文地址:https://www.cnblogs.com/Rainy7/p/csp-s-2020-first.html
Copyright © 2011-2022 走看看