bigbigli_大大李

CSP-J2019 NOIP普及组初赛真题(阅读程序部分)

阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填√,错误填×;除特殊说明外,判断题1.5分,选择题3分,共计40分)

#include <cstdio>
#include <cstring>
using namespace std;
char st[100];
int main() {
    scanf("%s", st);
    int n = strlen(st);
    for (int i = 1; i <= n; ++i) {
        if (n % i == 0) {
            char c = st[i - 1];
            if (c >= 'a')
                st[i - 1] = c - 'a' + 'A';
        }
    }
    printf("%s", st);
    return 0;
}

1)输入的字符串只能由小写字母或大写字母组成。()

正确答案: 错
解析:输入的字符串也可以包含数字等其他字符

2)若将第8行的“i = 1”改为“i = 0”,程序运行时会发生错误()

正确答案: 对
解析:若i可以为0,则第9行的if语句条件“n%i==0”将发生运行是错误RE。

3)若将第8行的“i <= n”改为“i * i <= n”,程序运行结果不会改变。()

正确答案: 错
解析:当第8行的循环条件为“i<=n”时,字符串的末尾字符会被程序加工,但若改为“i*i<=n”,字符串的末尾字符将不会被程序加工(除非字符串长度为1)。

4)若输入的字符串全部由大写字母组成,那么输出的字符串就跟输入的字符串一样。()

正确答案: 对
解析:大写字母的ASCLL编码值小于小写字母的。若输入的字符串全部由大写字母组成,则程序不会对其进行加工。

5)若输入的字符串长度为18,那么输入的字符串跟输出的字符串相比,至多有()个字符不同。
A. 18 B. 6 C. 10 D. 1

正确答案: B
解析:18的正约数共有6个,因此程序最多修改输入字符串中的6个字符,即输出字符串与输入字符串最多有6个字符不同。

6)若输入的字符串长度为(),那么输入的字符串跟输出的字符串相比,至多有36个字符不同。
A. 36 B. 100000 C. 1 D. 128

正确答案: B
解析:要使输出字符串和输入字符串之间最多有36个字符不同,36应当是字符串长度n的约数个数。本题选项中,仅有100000满足要求,分解质因数得25*55,正约数共有(5+1)*(5+1)=36个

学编程,找李老师
2.

#include<cstdio>
using namespace std;
int n, m;
int a[100], b[100];

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i)
        a[i] = b[i] = 0;
    for (int i = 1; i <= m; ++i) {
        int x, y;
        scanf("%d%d", &x, &y);
        if (a[x] < y && b[y] < x) {
            if (a[x] > 0)
                b[a[x]] = 0;
            if (b[y] > 0)
                a[b[y]] = 0;
               a[x] = y;
            b[y] = x;
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        if (a[i] == 0)
            ++ans;
        if (b[i] == 0)
            ++ans;
    }
    printf("%d", ans);
    return 0;
}

假设输入的n和m都是正整数,x和y都是在[1, n]的范围内的整数,完成下面的判断题和单选题:

1)当m>0时,输出的值一定小于2n。()

正确答案: 对
解析:由限定条件0<x,y<=n可知,当m>0时,一定存在某个数对被我们选中,此时ans<2n

2)执行完第27行的"++ans"时,ans —定是偶数。()

正确答案: 错
解析:由于数对是一个左值与一个由值相匹配,因此ans最终一定是偶数。但第27行的“++ans”在第23行的for循环内部,其中间结果可能为奇数。

3)a[i]和b[i]不可能同时大于0。()

正确答案: 错
解析:a[i]用于记录与左值i相匹配的右值,不存在则为0;b[i]用于记录与右值i相匹配的左值,不存在则为0.当存在数对(i,y)和(x,i)都被我们选中时,a[i]和b[i]就会同时大于0。

4)右程序执行到第13行时,x总是小于y,那么第15行不会被执行。()

正确答案: 错
解析:存在反例,依次考虑数对(1,2)(1,3)时,第15行程序会被执行。

5)若m个x两两不同,且m个y两两不同,则输出的值为()
A. 2n-2m B. 2n+2 C. 2n-2 D. 2n

正确答案: A
解析:此时,输入的数对两两互不冲突,因此程序会将他们全部选中,根据上述ans的意义可知,其结果为2n-2m。

6)若m个x两两不同,且m个y都相等,则输出的值为()
A. 2n-2 B. 2n C. 2m D. 2n-2m

正确答案: A
解析:此时,输入的数对两两存在冲突,因此程序最终只会选用一个数对,根据上述ans的意义可知,其结果为2n-2。

#include <iostream>
using namespace std;
const int maxn = 10000;
int n;
int a[maxn];
int b[maxn];
int f(int l, int r, int depth) {
    if (l > r)
        return 0;
    int min = maxn, mink;
    for (int i = l; i <= r; ++i) {
        if (min > a[i]) {
            min = a[i];
            mink = i;
        }
    }
       int lres = f(l, mink - 1, depth + 1);
    int rres = f(mink + 1, r, depth + 1);
    return lres + rres + depth * b[mink];
}
int main() {
    cin >> n;
    for (int i = 0; i < n; ++i)
        cin >> a[i];
    for (int i = 0; i < n; ++i)
        cin >> b[i];
    cout << f(0, n - 1, 1) << endl;
    return 0;
}

1)如果a数组有重复的数字,则程序运行时会发生错误。()

正确答案: 错
解析:若a数组有重复数字,则程序在根据a数组递归构造符合要求的二叉树时,对于相同结点值,会优先考虑位于左侧的。

2)如果b数组全为0,则输出为0。()

正确答案: 对
解析:程序最终输出的是各结点深度与b值得加权和,因此若b数组全为0,则加权和显然为0。

3)当n=100时,最坏情况下,与第12行的比较运算执行的次数最接近的是:()。
A. 5000 B. 600 C. 6 D. 100

正确答案: A
解析:最坏情况下,程序所构成的二叉树的每个结点最多有一个子结点,此时,程序将递归100层,其中第i层进行100-i+1次第12行的比较运算,总执行次数为100+99+98+...+1≈5000。

4)当n=100时,最好情况下,与第12行的比较运算执行的次数最接近的是:()。
A. 100 B. 6 C. 5000 D. 600

正确答案: D
解析:最佳情况下,程序构造二叉树时,对于每个结点会尽可能均分其左右子树。定义根结点深度为1,则含n=100个结点的树的深度最小为logn≈7,此时每选定一层结点,程序都需要执行约n次的第12行的比较运算,因此总执行次数约为nlogn≈600。

5)当n=10时,若b数组满足,对任意0<=i<n,都有b[i] = i + 1,那么输出最大为()。
A. 386 B. 383 C. 384 D. 385

正确答案: D
解析:此时,要使输出的ans值尽可能大,程序所构造的二叉树的深度应尽可能大。定义根结点深度为1,则含10个结点的二叉树的最大深度为10,因此ans的最大值为11+22+33+...+1010=385。

6)当n=100时,若b数组满足,对任意0 S i < 71,都有b[i]=1,那么输出最小为()。
A. 582 B. 580 C. 579 D. 581

正确答案: B
解析:此时,要使输出的ans值尽可能小,程序应参照完全二叉树构造此树,其中深度为1的结点共1个,深度为2的结点共2个,深度为3的结点共4个...深度为6的结点共32个,剩余37个结点的深度为7,因此ans的最小值为(11+22+33+...+632)+7*37=580。

posted @ 2020-08-19 16:50  bigbigli  阅读(3037)  评论(0编辑  收藏  举报