• 【初赛题解】CSP-J 2019 入门级 第一轮 第16题


    【题目】

    CSP-J 2019 入门级 第一轮 第16题
    阅读程序

    #include 
    #include 
    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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    判断题
    1.输入的字符串只能由小写字母或大写字母组成。()
    A. 正确
    B. 错误
    2.若将第 88 行的 i = 1 改为 i = 0,程序运行时会发生错误。()
    A. 正确
    B. 错误
    3.若将第 88 行的 i <= n 改为 i * i <= n,程序运行结果不会改变。()
    A. 正确
    B. 错误
    4.若输入的字符串全部由大写字母组成,那么输出的字符串就跟输入的字符串一样。()
    A. 正确
    B. 错误
    选择题
    5.若输入的字符串长度为 1818,那么输入的字符串跟输出的字符串相比,至多有()个字符不同。
    A. 18
    B. 6
    C. 10
    D. 1
    6.若输入的字符串长度为(),那么输入的字符串跟输出的字符串相比,至多有 3636 个字符不同。
    A. 36
    B. 100000
    C. 1
    D. 128

    【题目考点】

    1. 字符、字符数组
    2. 约数

    整数n可以分解质因数为 n = p 1 a 1 p 2 a 2 . . . p k a k n=p_1^{a_1}p_2^{a_2}...p_k^{a_k} n=p1a1p2a2...pkak
    根据乘法原理,可知n的约数个数为: ( a 1 + 1 ) ( a 2 + 2 ) . . . ( a k + k ) (a_1+1)(a_2+2)...(a_k+k) (a1+1)(a2+2)...(ak+k)

    【解题思路】

    易知st是存储字符串的字符数组,n是字符串的长度。
    接下来看下一段for循环:

     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';
            }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    i从1到n循环,而下面代码中使用i的地方都是st[i-1],因此可以看出,i指的是当前字符串中的第几个字符(从1开始数)。
    n%i==0,n是i的整数倍,或者说i是n的约数。
    那么取第i个字符(从1开始)为c。
    根据ascii码原理,c >= 'a'可以理解为如果这个字符是小写字母。c-'a'+'A'可以理解为将c从小写字母转为大写字母。
    那么该段代码的含义为:i从1到n循环,如果i是n的约数,那么第i(从1开始)个字符如果是小写,变为大写。
    这段代码的功能清楚了,就可以做题了。

    1.输入的字符串只能由小写字母或大写字母组成。()
    错误,字符串中可以有字母,也可以有其它字符。
    2.若将第 88 行的 i = 1 改为 i = 0,程序运行时会发生错误。()
    正确。i初值为0的话,n%i==0可能会出现n%0的情况,这就是除0,会产生运行时错误。
    3.若将第 88 行的 i <= n 改为 i * i <= n,程序运行结果不会改变。()
    错误。会改变,因为如果 i > n i>\sqrt{n} i>n ,还是可能是n的约数的。比如n为10,那么满足n%i==0的i有1,2,5,10,其中5和10都是i*i > n的数字,如果代码是i <= n,那么第5和第10字符(从1开始)会从小写变为大写。如果代码是i*i <= n,则不会发生。
    4.若输入的字符串全部由大写字母组成,那么输出的字符串就跟输入的字符串一样。()
    正确。对字符串的改动只有小写变大写。都是大写字母的话,就不会变。
    5.若输入的字符串长度为 18,那么输入的字符串跟输出的字符串相比,至多有()个字符不同。
    A.18 B.6 C.10 D.1

    字符可以改变的位置(从1开始),即为18的约数。看18有几个约数,那么就最多可以改变几个字符。18的约数有1,2,3,6,9,18,共6个,选B。
    6.若输入的字符串长度为(),那么输入的字符串跟输出的字符串相比,至多有 36 个字符不同。
    A. 36
    B. 100000
    C. 1
    D. 128

    就是看哪个数字的约数有36个。
    判断一个数字的约数的个数,可以先分解质因数,比如 36 = 2 2 ∗ 3 2 36=2^2*3^2 36=2232,作为36的约数,一定是0个或多个质因数的乘积。质因数2可以取0,1,2个,质因数3可以取0,1,2个,根据乘法原理,共有 3 ∗ 3 = 9 3*3=9 33=9
    求约数个数公式见上面【题目考点】。
    同理: 128 128 128 = 2 7 2^7 27,约数有8个。
    1的约数只有1个。
    此时通过排除法可以选B了。
    算一下B选项: 100000 = 1 0 5 = 2 5 ∗ 5 5 100000=10^5=2^5*5^5 100000=105=2555,约数个数为 ( 5 + 1 ) ( 5 + 1 ) = 36 (5+1)(5+1)=36 (5+1)(5+1)=36
    选B。

    【答案】

    1. B
    2. A
    3. B
    4. A
    5. B
    6. B
  • 相关阅读:
    nginx加权轮询,upstream,Keepalive,负载均衡实现案例
    java计算机毕业设计计算机office课程平台MyBatis+系统+LW文档+源码+调试部署
    金三银四来了-找工作有哪些平台/工具?
    【spring】一文读懂SpringIOC和AOP
    常用的35个Linux命令合集
    Spring Boot+Vue3前后端分离实战wiki知识库系统之后端架构完善与接口开发
    微信怎么把ip地址改成域名
    SpringCloud(七) - 微信支付
    七夕蛤蟆--自动发消息脚本
    mybatis-spring的整合
  • 原文地址:https://blog.csdn.net/lq1990717/article/details/126646299