记录自己做C语言经典100题的训练过程(6~20)
- 第六题:
- 第七题:
- 第八题:
- 第九题:
- 第十题:
- 第十一题:
- 第十二题:
- 第十三题:
- 第十四题:
- 第十五题:
- 第十六题:
- 第十七题:
- 第十八题:
- 第十九题:
- 第二十题:
第六题:
用*号输出字母C的图案
解题思路:用8x8的矩阵来打印字母C的图案,通过打印不同行不同的星号与空白实现。
int rows = 0;//定义要多少行来实现C的打印
int i;//定义变量控制打印的空白与星号
while (rows < 8)
{
if (rows == 0 || rows == 7) //第0行和第7行一样
{
for ( i = 0; i < 8; i++)
{
if (i < 4)
printf(" ");//打印4个空白
if (i >= 4 && i <= 6)
printf("*");//打印3个星号
}
printf("\n");
}
else if (rows == 1 || rows == 6) //第1行和第6行一样
{
for (i = 0; i < 8; i++)
{
if (i == 3 || i == 7)
printf("*");//在第4处与第8处打印星号
else
printf(" ");
}
printf("\n");
}
//其余行一样;
else
{
for (i = 0; i < 2; i++)
printf(" ");//打印两个空白
printf("*");//在第3处打印星号
printf("\n");
}
rows++;
}
程序打印的结果:
不是很推荐用prinf完成这个题的解答,因为这样感觉违背了出这个题的想法。
第七题:
输出特殊图案,请在c环境中运行,看一看,Very Beautiful!
解题思路:选择输出X形图案
int rows = 0;
int position1 = 0;
int position2 = 6;//定义两个变量用来控制空白与图案
while (rows < 7)
{
if (rows != 3)
{
for (int j = 0; j < 7; j++)
{
if (j == position1 || j == position2) //用两个变量的递增与递减来实现随着行数变化,星号与图案打印的位置也变化
{
printf("*");
}
else
printf(" ");
}
position1++;
position2--;
printf("\n");
}
if (rows == 3) //打印到中间行就只打印一个*号
{
for (int j = 0; j < 7; j++)
{
if (j == 3)
printf("*");
else
printf(" ");
}
printf("\n");
position1++;
position2--;
}
rows++;
}
打印图案:
依旧和第六题一样,不推荐使用printf完成。
第八题:
输出9*9口诀。
解题思路:用两个变量控制行列,在控制行列的同时打印口诀。
int i, j;//用i控制行,j控制列
for (i = 1; i <= 9; i++)
{
for (j = 1; j <= i; j++)
{
printf("%2d *%2d = %2d ", j, i, i*j);
}
printf("\n");
}
这个题还是容易做的,唯一需要注意的是 j 应该小于等于 i 。
第九题:
要求输出国际象棋棋盘。
解题思路:国际象棋棋盘也就是输出8x8的黑白棋盘
int i, j;//定义两个变量来控制黑白的打印
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
if ((i + j) % 2 == 0)
{
printf(" ");
printf("%c%c", 168, 128);
}
else
printf(" ");
printf("\n");
}
这题易解,自己打印的图形有什么不对的话,再加以调整就OK了。
第十题:
打印楼梯,同时在楼梯上方打印两个笑脸
解题思路:
int i, j;
printf("\1\1\n"); //打印两个笑脸
for (i = 1; i < 15; i++)
{
for (j = 0; j <= i; j++)
printf("%c%c", 168, 128);
printf("\n");
}
这题可能唯一难在打印笑脸,这个需要查阅ASCII码表。当然现在的VS2013以上的版本打印不出笑脸,这是因为console的版本,如果你非要打印笑脸的话,建议把版本调低就行。
第十一题:
古典问题(兔子生崽):有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?(输出前40个月即可)
解题思路:先在纸上简单的写下前8个月,每个月的总数,会发现兔子的数量符合
1 1 2 3 5 8 13 21 … 这就是斐波那契数列。
int number[40];//定义数组用来存放每个月兔子的总数
//定义初始的每个月的兔子数
number[0] = 1;
number[1] = 1;
for (int i = 0; i < 40; i++)
{
//每5个数换行,保证打印的数字是直观的
if (i % 5 == 0)
printf("\n");
//前2个月都是1
if (i < 2)
{
printf("%4d ", number[i]);
}
//后两个月直接前1个月+前2个月这样不停地计算即可得到结果
else
{
number[i] = number[i - 1] + number[i - 2];
printf("%4d ",number[i]);
}
}
用数组来处理这个问题是最方便的。
第十二题:
判断 101 到 200 之间的素数。
解题思路:
①、素数:除了1和它本身之外不能被其他数整除
②、我们以18举例,这不是一个素数,但是它可以由:1 x 18,2 x 9 , 3 x 6 , 6 x 3 , 9 x 2 , 18 x 1组成。但是我们会发现,再经过3 后,就是重复的,这时我们为提高效率。可以让数去除以2 到 这个数的平方。因为再增加就只是重复计算,换了位置而已
int Sqrt(int number);
int main(void)
{
int number;//用来存储开方数
//从101到200计数
for (int i = 101; i <= 200; i++)
{
number = Sqrt(i);
int flag = 0; //定一个标志位用来判断
//这一个for循环用来不停地判断是否为素数
for (int j = 2; j <= (number+1); j++)
{
if (i % j == 0) //然后对其取余,来判读是否可以整除
{
flag++;
break;
}
}
if (flag == 0)
{
printf("%5d", i);
}
}
return 0;
}
int Sqrt(int number)
{
return number / 2;
}
注意:在代码中对其是否为素数的判断。一是number要加1,二是取余不是除,做这个题时真是粗心啊。
第十三题:
打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数 本身。例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。
解题思路:
两种思路:
①、在100~999这个循环中,用3个循环,不停地去找合适的百位数、十位数、个位数,再用if判断即可
②、在100~999这个循环中,提取出百位、十位、个位,然后各自三次方,再if判断即可。
int Cubic(int number);
int main(void)
{
//在100到999中去找水仙花数
int bai;
int shi;
int ge;
int result;
for (int start = 100; start < 1000; start++)
{
bai = start / 100;
shi = (start - 100 * bai)/10;
ge = (start - 100 * bai - 10 * shi);
result = Cubic(bai) + Cubic(shi) + Cubic(ge);
if (start == result)
printf("%5d", start);
}
return 0;
}
int Cubic(int number)
{
return number*number*number;
}
这个题还是很容易求解的
第十四题:
将一个正整数分解质因数。例如:输入90,打印出90=233*5。
解题思路:一是要判断是否为素数。二是若不为素数,则开始进行分解,每分解一个数,被测试的数就要发生变化。
int main(void)
{
int input;
printf("Please enter the number which you want to disintegrate:");
scanf("%d", &input);
int flag = 0;//用于判断所输入的数是否为素数
printf("%d = ", input);
int test;
test = input;
for (int i = 2; i <= test; i++)
{
while (test % i == 0)
{
if (i != input) //避免是素数打印 37 = 37 这样的情况
{
flag = 1;//证明这个数不是素数
printf("%d ", i);
}
test /= i;
if (test != 1)
printf("*");
}
}
if (flag == 0)
printf("1 * %d", input);
}
这个代码。我考虑的较为周全些,避免了 如果是素数,会打印 37 = 37 这样的情况。而不是 37 = 1 * 37 这样的情况。
第十五题:
利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。
解题思路:此题用三目运算符来写,是最为简洁的。
int score;
printf("Please enter your score:");
scanf("%d", &score);
printf("Your grade is %c", (score >= 90 ? 'A' : (score >= 60 ? 'B' : 'C')));
此题可用if去判断,但我们可以使三目运算符的嵌套去精简代码。
第十六题:
输入两个正整数m和n,求其最大公约数和最小公倍数。
解题思路:
首先需要明白两个概念:
最大公约数:两个整数中共有约数最大的一个
最小公倍数 : 最小公倍数 = 两数的乘积 / 最大公约数。
然后,很明显我们需要先找到最大公约数,再求得最小公倍数
最大公约数:辗除法,(可以从原理去解释,这里直接拿来主义)
int gcd(int m, int n);
int main(void)
{
int m, n; //定义输入变量
printf("Please enter two integer:");
scanf("%d %d", &m, &n);
printf("Greast common dividor is %d,least common multipe is %d ", gcd(m, n), m * n / gcd(m, n));
return 0;
}
int gcd(int m, int n)
{
int temp;
if (m < n)
{
temp = m;
m = n;
n = temp;
}
while (n > 0)
{
temp = m%n;
m = n;
n = temp;
}
return m;
}
这个题可能唯一的麻烦在于去理解辗除法,不过这个算法网上有证明,有兴趣的小伙伴可以去再学习下。如果只是拿来用,倒是很容易解决这道题目。
第十七题:
输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
解题思路:可以利用ASCII码去判断,但我觉得更为简洁的方法是调用#include<ctype.h>中的函数。
char st[40];
int Alpha = 0; //字符
int Number = 0; //数字
int Blank = 0; //空白
int Other = 0; //其他字符
int i = 0;
fgets(st, 20, stdin);
while ( st[i] != '\0')
{
if (isalpha(st[i]))
Alpha++;
else if (isalnum(st[i]))
Number++;
else if (st[i] == ' ')
Blank++;
else
Other++;
i++;
}
printf("字母 %d 个, 数字 %d 个, 空白 %d 个 , 其他 %d 个", Alpha, Number, Blank, Other);
这题还是容易做的。
第十八题:
求s=a+aa+aaa+aaaa+aa…a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制。
解题思路:这题容易解,就是不断的增加位数即可。
int number, amount; //定义数字和个数
int start; //用来存储初始放入的值
int count = 1; //用来位数的递增
int result = 0; //用来存储结果
printf("Please enter the number and the times:");
scanf("%d %d", &number, &amount);
start = number;
while (amount > 0)
{
result += number;
count *= 10;
number = number + start * count; //这里一定注意start必须是输入的数,小心写成number
amount--;
}
printf("This result is %d ", result);
这里要小心的就是number = number + start * count;这行代码,刚写的是写成number结果就炸了,后面检查才发现错误。
第十九题:
一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如6=1+2+3.编程找出1000以内的所有完数。
解题思路:注意这里1被算做因子,但是本身的6不算做因子。只需要找到所有的因数,然后再相加,再与原来的数进行判断即可得到想要的答案。
int end = 1000;
int result;
for (int i = 2; i <= end; i++)
{
result = 0; //每完成一次循环需要把结果清零掉
for (int j = 2; j < i; j++)
{
if (i % j == 0)
result += j; // 只要可以整数的数都应该加在一起,然后把因子相加在一起
}
if ((result + 1) == i)
printf("%4d", i); //然后把对应的数i打印出来
}
printf("\n");
注意是因子的数相加,还有就是打印的是i不是result,result只是用来判断的
第二十题:
一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
解题思路:其实就是不停地把100米对半分10次。
float height = 100; // 初始高度
int time = 1; //用于计算落地的次数
float distance = 100; //这是第一次落地后经过的路程
//我们从第一次落地后开始计算
while (time < 10)
{
height /= 2;
distance += 2*height;
time++;
}
//需要注意第10落地后,高度需要再除以2才是第10次反弹。
printf("The distance is %f .past 10 times tthe height is %f ", distance, height/2);
需要注意的是:落地先于反弹。其次从第2次落地开始计算,方便于直接对高度乘以2。因为第一次落地后到第二次落地经过的路程= 第一次反弹的高度的2倍 。
更多推荐
C语言100题(6~20)
发布评论