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_0、cnt_1以及sum,它们分别用于记录数字0的数量、数字1的数量以及英文字母各自位置代码之和。
依次读取每个字符,在发现一个换行符时,则将其转换为对应的数字代码,并将其累加至变量sum里。
计算二进制表示中的 0 和 1 的个数:
循环对变量 sum 进行迭代,每次循环除以2,直到 sum 的值为 0。
检查最低位的值:
-
若输入值为 x:
- 当 x = ₁ 则:
- 将操作标记设为 op = A
- 当 x = ₀ 则:
- 将操作标记设为 op = B
- 当 x = ₁ 则:
-
输出操作标记
将变量 cnt0 和 cnt1 的值输出为结果。
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)
还没有任何评论哟~
