1.求最大公约数和最小公倍数(注意溢出问题)
题目描述
输入两个正整数,输出其最大公约数和最小公倍数。
输入
输入两个正整数n和m(n,m<=1000000)。输入保证最终结果在int范围内。
输出
输出两个整数,用空格隔开。表示m和n的最大公约数和最小公倍数。
样例输入
4 6
样例输出
2 12
提示
注意运算过程中的溢出问题
//求两个整数的最大公约数和最小公倍数
#include<stdio.h>
//求最大公约数辗转相除法
int gcd(int num1, int num2)
{
while (num2 != 0)
{
int temp = num2;
num2 = num1 % num2;
num1 = temp;
}
return num1;
}
//求最小公倍数,两个数相乘除以最大公约数
int lcm(int num1, int num2)
{
long long a = (long long)num1 * num2;//进行强制类型转换,防止溢出。
int b = gcd(num1, num2);
return a / b;
}
int main()
{
int num1, num2;
scanf("%d %d", &num1, &num2);
int resual1 = gcd(num1, num2);
int resual2 = lcm(num1, num2);
printf("%d %d", resual1, resual2);
return 0;
}
int类型之间的加或乘都有可能导致溢出,这样会造成数据的丢失。为了避免发生溢出,就进行强制类型转换,将int类型的数据在计算前就要进行转换,计算的结果也是转换后的类型。
2.加密字符(输入的字符串长度不确定)
题目描述
从键盘输入一批字符,以@结束,按要求加密并输出。
输入
从键盘输入一批字符,占一行,以@结束。
输出
输出占一行
加密规则:
1)所有字母均转换为小写。
2)若是字母'a'到'y',则转化为下一个字母。
3)若是'z',则转化为'a'。
4)其它字符,保持不变。
样例输入
Kyh520@
样例输出
lzi520
#include <stdio.h>
int main() {
char ch;
while ((ch = getchar()) != '@') {
if (ch >= 'A' && ch <= 'Z') {
ch = ch - 'A' + 'a';
}
if (ch >= 'a' && ch < 'z') {
ch++;
}
else if (ch == 'z') {
ch = 'a';
}
putchar(ch);
}
return 0;
}
3.统计数字字符的个数(输入的字符串长度不确定)
题目描述
输入一行字符,以回车符作为输入结束的标志。统计其中数字字符的个数。
输入
多个字符,以回车符结束,回车符不作为有效字符。
输出
输出一个整数,表示数字字符的个数。
样例输入
12abrt12@2013
样例输出
8
#include<stdio.h>
int main()
{
int count = 0;
char ch;
while ((ch = getchar()) != '\n')
{
if (ch >= 48 && ch <= 57)
count++;
}
printf("%d", count);
return 0;
}
这种情况下,如果使用字符数组,那数组的大小没有办法确定,这样会造成输出超限的问题。
4.字符分类统计(在统计时不能忽略空格字符)
题目描述
输入一行字符,以回车符作为输入结束的标志。统计其中英文字母、数字字符和其他字符的个数。
输入
多个字符,以回车符结束,回车符不作为有效字符。有效字符个数不超过100。
输出
输出分3行,格式见输出样例。
样例输入
Abse 4+5*3=? //注意输入的内容中有空格
样例输出
letter:4
digit:3
other:5 //输出中的数据包括空格在内
#include<stdio.h>
int main()
{
int letter = 0;
int digit = 0;
int other = 0;
char ch;
while ((ch = getchar()) != '\n')
{
if (ch <= 'Z' && ch >= 'A')
letter++;
else if (ch <= 'z' && ch >= 'a')
letter++;
else if (ch <= '9' && ch >= '0')
digit++;
else
other++;
}
printf("letter:%d\n", letter);
printf("digit:%d\n", digit);
printf("other:%d", other);
return 0;
}
5.有问题的里程表(数字的位运算和处理,)
题目描述
某辆汽车有一个里程表,该里程表可以显示一个整数,为该车走过的公里数。然而这个里程表有个毛病:它总是从3变到5,而跳过数字4,里程表所有位(个位、 十位、百位等)上的数字都是如此。例如,如果里程表显示339,汽车走过1公里之后,该里程表显示350。
输入
输入一个整数num,表示里程表显示的数值,1 < num < 1000,且一定不含整数4。
输出
输出一个整数,为该汽车实际行驶的公里数。例如,如果该里程表显示55,则实际走过的公里 数是40。
样例输入 Copy
106
样例输出 Copy
86
有问题的里程表
第一种方法
#include<stdio.h>
int main()
{
int num = 0;
int count = 0;
scanf("%d", &num);
while (num > 0)//通过计算不带4的数字的个数来重新计算里程,前提是历程小于1000
{
if (num % 10 != 4 && num / 10 % 10 != 4 && num / 100 != 4)
count++;
num--;
}
printf("%d", count);
return 0;
}
第二种方法
#include<stdio.h>
int cont(int num)
{
int resual = 0;//最终结果
int factor = 1;//权重
while (num > 0)
{
int digit = num % 10;//逐个获得里程表中的每一个数字
if (digit > 4)
digit--;//如果大于四就--
resual += digit * factor;//将处理后的数字称以对应的权重,累加到结果中。
factor *= 9;//将权重更新为原来的9倍
num /= 10;//将里程表的数字除以10,处理下一位数字,同时也是结束循环的条件
}
return resual;
}
int main()
{
int num;
int count;
scanf("%d", &num);
count = cont(num);
printf("%d", count);
return 0;
}
这个问题主要考察以下几个方面:
- 数字的位运算和处理能力:需要对输入的整数进行逐位分析和处理,涉及到取余、除法等操作来获取每一位数字。
- 逻辑思维能力:理解题目中特殊的里程表规则,并根据规则进行正确的转换计算。
- 算法设计能力:设计一个合适的算法来实现从有问题的里程表数值到实际行驶公里数的转换。
6.二进制转换为十进制
题目描述
将一个二进制数,转换为对应的十进制数。
输入
输入一个只含有’0’和’1’的字符串,以回车结束,表示一个二进制数。该二进制数无符号位,长度不超过31。
输出
输出一个整数,为该二进制数对应的十进制数。
样例输入 Copy
100000000001
样例输出 Copy
2049
提示
(1) 整数运算尽量避免pow之类的double类型函数,以免截断取整带来错误。 (2)可使用递推思想,充分利用中间结果。类似思想可参考秦九韶算法。秦九韶算法是中国南宋时期的数学家秦九韶提出的一种多项式简化算法。计算一次多项式f(x) = a0*xn + a1*x(n-1) + ... + an 只需要n次乘法和n次加法。原理是一次多项式f(x)可写成如下加括号方式:f(x) =(( (a0*x + a1)*x + a2) * x + ... an-1) * x + an。自内向外去括号计算,只需要n次乘法和n次加法。
本题从高位到低位依次输出二进制数,对应多项式系数a0, a1,....,an, 而x的值为2。递推过程如下:
d = 0;
while( ch = getchar(), ch != '\n')
d = d * 2 + (ch - '0');
#include<stdio.h>
int main()
{
char ch;
long long d = 0;
while ((ch = getchar()) != '\n')
{
d = d * 2 + (ch - '0');
}
printf("%lld",d);
return 0;
}