C程序设计(谭浩强版)第五章课后习题

1.输入两个正整数m和n,求其最大公约数和最小公倍数

可以看一下我的这个文章C语言实现最小公倍数和最大公约数


2.输入一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数

英文字母的判定 :要满足两种情况

a<=且<=z&&A<=且<=Z

代码如下:

int main( ) {
	
	//输入一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数
	char c;
	int num = 0, eng = 0, spac = 0, other = 0;
	printf( "请输入一行字符:\n" );
	while ((c=getchar())!='\n' ) {
		if ( c >= 'a' && c <= 'z'  || c >= 'A' && c <= 'Z'  ) {//判定是否为字母
			eng++;
		}
		else if (c==' ' )//判定空格
		{
			spac++;
		}
		else if ( c>='0'&&c<='9' )//判定数字条件
		{
			num++;
		}
		else
		{
			other++;
		}
	}
	printf( "字母的个数为:%d\n空格的个数为:%d\n数字的个数为:%d\n其它字符数为:%d\n", eng, spac, num, other );
	return 0;
}

效果如下:


3.求的值,

其中a是一个数字,n表示a的位数,n由键盘输入。例如2+22+222+2222+22222(此时n=5)

这个公式的规律其实很简单,比如设a1=2,a2=a1*10+a1=22,a3=a2*10+a2...

可以很容易地发现规律,我们需要两个存储值的变量,

一个存储a2,a3...的值,一个存储总共和Sn的值

我们需要借助循环,可以看到n=5的时候,一共有五个数字相加

所以循环的范围也是<=n的,

代码如下:

int a, n;
	int sum = 0, num = 0;
	scanf_s( "%d ,%d", &a, &n );
	printf( "请输入a和n的值:\n" );
	for ( int i = 1; i <= n;i++) {
		num = num + a;       
		sum = sum + num;
		a = a * 10 ;
	}
	printf( "和为:%d", sum );

每一次的循环,a的值都会改变

以a=2,n=5为例

第一次循环时 num=0+2=2,sum=0+2=2

第二次循环时 num=2+2*10=22,sum=2+22=24

第三次循环时 num=22+200=222,sum=24+222=246

第四次循环时 num=222+2000=2222,sum=246+2222=2468

第五次循环时 num=2222+20000=22222,sum=2468+22222=24690

每一次num的值都是更新后的a与之前未更新前的num相加

然后sum来进行累加每一次num的值 最后输出结果

效果如下:


 4.求(即求1!+2!+3!+4!+...+20!)

这个就比较简单了就是1-20的阶乘相加

代码如下:

double sum = 0;
	double t = 1;
	for ( int i = 1; i <= 20;i++ ) {
		t = t * i;
		sum += t;
	}
	printf( "和为:\n%lf", sum );

注意:

不要将sum和t的值设成init类型,因为int类型在内存中占两个字节,整数的范围为-32768-32767

故将sum和t设为double类型,以获得更多的精度。

效果如图:


 5.求++

 第一个式子就是求1-100的和

第二个式子就是求1-50的平方和

第三个式子就是求1-10的倒数和

代码如下:

int sum = 0, sum1 = 0, sum2 = 0, sum3 = 0;
	for ( int i = 1; i <= 100;i++ ) {
		sum1 += i;
	}
	for ( int i = 1; i <= 50;i++ ) {
		sum2 += i * i;
	}
	for ( int i = 1; i <= 10;i++ ) {
		sum3 += 1 / i;
	}
	sum = sum1 + sum2 + sum3;
	printf( "1-100的累加和为:%d\n", sum1 );
	printf( "1-50的平方和为:%d\n", sum2 );
	printf( "1-10的倒数和为:%d\n", sum3 );
	printf( "三项的和为:%d\n", sum );

 效果如图:


6.输出所有的“水仙花数”。所谓“水仙花数”就是指一个3位数,其各位数字立方和等于该数本身。

例如,153时一个水仙花数,因为153=

乍一看题目确实有可能被吓住,但要慢慢发现规则。

他其实这个判定条件很简单

1.三位数(100<=&&<1000)

2.个位数字的立方+十位数字的立方+百位数字的立方=它本身

代码如下:

#include<stdio.h>
#include<math.h>
int main( ) {
	int j, k, a;
	//j百位;k十位;a个位
	
	for ( int i = 100; i < 1000;i++ ) {
		j = i / 100;//百位
		k = ( i % 100 ) / 10;//十位
		a = i % 10;//个位
		if (i==(pow(j,3)+pow(k,3)+pow(a,3)) ) {
			printf( "%d是水仙花数", i );
			printf( "\n" );
		}
	}

	return 0;
}

效果如下:


7.一个数如果恰好等于他的因子之和,这个数就称为”完数“。

例如,6的因子为1,2,3,而6=1+2+3,因此6是”完数“。

编程序找出1000之内的所有完数,并按下面格式输出其因子。

6 its factors are 1,2,3

关于这一题我们至少要用到循环的嵌套

我们用sum来盛放能整除的因数和

切记:每一次循环结束 sum都要及时清零

因为每一次循环的数字都是不一样的,不要将int sum=0写在全局变量中。

代码如下:

int i, j;
	int sum;
	for ( i = 2; i < 1000;i++ ) {
		sum = 0;
		for ( j = 1; j < i;j++) {
			if ((i%j)==0 ) {
				sum += j;  //sum=所有被整除因子的和
			}
		}
		if (sum==i ) {
			printf( "%d its factors are ", i );
			for ( j = 1; j < i;j++ ) {
				if ((i%j)==0 ) {
					printf( "%d ", j );//输出所有因子
				}				
			}
			printf( "\n" );
		}
	}

至于为什么循环从2开始,那是因为0和1是特殊情况我们就避开他们从2开始了

效果如下:


8.有一个分数序列:

,,,,,,...

求出这个数列的前20项之和。

细心观察可以发现第一项的分子+分母=第二项的分子,

第二项的分母=第一项的分子

这样想就很简单了

代码如下:

double b=1;//分母
	double a = 2;//分子
	double sum = 0;
	double t;
	for ( int i = 1; i <= 20;i++) {
		sum += a / b;//累加每一次的分式
		t = a;//将前一次的分子赋给t储存
		a += b;//后一次的分子=前一次的分子+分母
		b = t;//将分子储存在t中的值赋给分母
	}
	printf( "前20项之和为:%lf\n", sum );

注意:

不要直接将分子a的值赋给b(b=a;a=a+a),否则后一项的分子就会等于a+a了!

需要一个中转变量(也就是此处t)

效果如下:


9.一个球从100m高度自由落下,每次落地后反弹回原高度的一半,再落下,再反弹。

求他在第10次落地时共经过多少米,第十次反弹多高。

因为要算十次的高度总和,故需要把每一次弹起的高度进行累加

第一次可以算出来50*2=100米(弹起高度和落下高度算作一次弹起)

代码如下:

    double m = 100;
	double dis = 100;//第一次弹起经过的高度(弹起高度+落下高度算一次弹起)
	for ( int i = 1; i <= 10;i++ ) {
		m /= 2;//将每次的高度/2
		dis += m * 2;
	}
	printf( "共经过%lf米\n", dis );
	printf( "反弹%lf米", m );

效果如下:


10.猴子吃桃问题。猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。第十天早上想再吃的时候,就只剩一个桃子了。求第一天共摘了多少个桃子。

 代码如下:

int x ;//x为前一天的桃子数
	int xx=1;
	for ( int i = 9; i >0;i--) {
		x = ( xx + 1 ) * 2;//根据前一天的桃子数计算出前前一天的桃子数
		//比如根据第九天的桃子算出第八天的桃子数
		xx = x;//然后将第八天的桃子数当作乘数,算出第七天的桃子数
	}
	printf( "第一天共摘了%d个", x );

效果如下:


11.输出以下图案:

我们不妨先来分析一下,乍一看还是挺吓人的

其实就是7*7的星星矩阵,然后将四个角都用空格代替。

代码如下:

int i, j,k;
	for ( i = 0; i <=3;i++ ) {
		for ( j = 0; j <=2-i;j++ ) {
			printf( " " );
		}
		for ( k = 0; k <= 2*i;k++) {
			printf( "*" );
		}
		printf( "\n" );
	}
	for ( i = 0; i <= 2;i++ ) {
		for ( j = 0; j <= i;j++ ) {
			printf( " " );
		}
		for ( k = 0; k <= 4 - 2 * i;k++) {
			printf( "*" );
		}
		printf( "\n" );
	}

 原理很简单,这个图案是由上下两部分组合在一起的,最外面的变量i控制行,变量j控制列

当i=0的时候,j=0,1,2,因此(0,0),(0,1),(0,2)执行空格请求  三个空格

当i=1时,j=0,1,因此(1,0),(1,1)执行空格请求                          两个空格

当i=2时,j=0,因此(2,0)执行空格请求                                 一个空格

当i=3时,情况不成立,故没有空格请求

当i=0时,k=0,因此本应该在(0,0)的位置进行画” * “操作,因为前面的操作中在(0,0)-(0,2)添加了空格,因此*的位置就排在了他们的后面也就是(0,3)的位置

当i=1时,k=0,1,2,依次往后类推,空格占据了(1,0),(1,1),*就排在了(1,2),(1,3),(1,4)

当i=2时,k=0,1,2,3,4  ,有5个星星

当i=3时,k=0,1,2,3,4,5,6.有7个星星

至此上半部分的逻辑就是如此

 效果如下:

 至于下半部分,只不过和上半部分反着来的,鼓励读者自己通过思考获得结果

 有不对的问题欢迎指正!感谢大家!

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WhispFlow

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值