Advertisement

1057 数零壹【PAT (Basic Level) Practice (中文)】

阅读量:

1057 数零壹【PAT (Basic Level) Practice (中文)】

原题链接1057 数零壹 (pintia.cn)

1.前言

PAT(乙级)2016年秋季考试 第二题

分数: 20

难度:⭐️⭐️⚝⚝⚝

知识点:

复制代码
* C程序设计/循环控制/while和do-while
* C程序设计/数组/字符串

方法技巧

复制代码
* 位运算

运行限制

代码长度限制 16 KB
时间限制 200 ms
内存限制 64 MB

2.题目描述

假设有一条长度至多为 10^5 的字符串 S,请完成以下计算:对 S 中的每个英文字母(不论大小写),将其对应的顺序数(a-z对应数字1到26)累加求和得到一个整数 N;然后对这个整数 N 进行二进制分解统计,在结果中分别记录其中出现的0的数量和1的数量。例如对于字符串 PAT (Basic) 来说:P对应的是第16个字母、A是第1个、T是第20个等等,则这些顺序数相加的结果为71;将其转换为二进制形式即为 1000111,在这串二进制数字中包含了3个零以及4个一。

输入格式:

输入在一行中给出长度不超过 10^5、以回车结束的字符串。

输出格式:

请依次在一行中呈现 0 的数量和 1 的数量,并以空格分隔开。特别注意:如果输入字符串中不含字母字符,则N为零。

输入样例:

复制代码
    PAT (Basic)

输出样例:

复制代码
    3 4

3.解题思路

3.1题目分析

计算给定字符串中所有英文字母的ASCII码值之和以获得整数N。然后分析该整数N在其二进制表示形式中含有多少个 0 和多少个 1

3.2基本思路

将给定字符串中的每个英文字母依次映射为对应的序号值,并将这些数值累加求得一个总和N;然后对这个总值N反复进行除以2的模运算;最后统计运算结果序列中出现的0与1的数量。

3.3详解步骤

初始化变量为cnt_0cnt_1以及sum,它们分别用于记录数字0的数量、数字1的数量以及英文字母各自位置代码之和。

依次读取每个字符,在发现一个换行符时,则将其转换为对应的数字代码,并将其累加至变量sum里。

计算二进制表示中的 0 和 1 的个数:

循环对变量 sum 进行迭代,每次循环除以2,直到 sum 的值为 0。

检查最低位的值:

  • 若输入值为 x

    • x = ₁ 则:
      • 将操作标记设为 op = A
    • x = ₀ 则:
      • 将操作标记设为 op = B
  • 输出操作标记

将变量 cnt0cnt1 的值输出为结果。

4.参考答案

复制代码
    #include <stdio.h>
    
    int main(){
    char c;
    int cnt0, cnt1, sum;
    
    // 初始化计数器和和变量
    cnt0 = cnt1 = sum = 0;
    
    // 读取输入字符
    scanf("%c", &c);
    
    // 循环读取字符直到遇到换行符
    while (c != '\n') {
        // 检查字符是否为小写字母,如果是则将其序号加到 sum 中
        if (('a' <= c) && (c <= 'z'))
            sum += (c - 'a' + 1);
        // 检查字符是否为大写字母,如果是则将其序号加到 sum 中
        else if (('A' <= c) && (c <= 'Z'))
            sum += (c - 'A' + 1);
    
        // 继续读取下一个字符
        scanf("%c", &c);
    }
    
    // 计算 sum 的二进制表示中 0 和 1 的个数
    while (sum) {
        if (sum % 2)
            cnt1++;
        else
            cnt0++;
    
        // 将 sum 右移一位,相当于将其除以 2
        //位运算比除法更高效
        sum = sum >> 1;
    }
    
    // 输出结果
    printf("%d %d\n", cnt0, cnt1);
    
    return 0;
    }

全部评论 (0)

还没有任何评论哟~