【勇敢牛牛,不怕困难】有手就行栏目:头歌教学平台 - 湖南工业大学刘强老师的C语言函数实战课堂作业答案 - > - > {求和+回文数计算+编写函数求表达式的值+阶乘数列+亲密数+公约数公倍数求解}

在这里插入图片描述

在这里插入图片描述

第一关:求和

任务描述
题目描述:给你一个n,要求你编写一个函数求1+2+…+n.

输入
输入一个n
输出
输出1+2+…+n的和

测试说明
样例输入:
100
样例输出:
5050

分析:

这个是真的,有手就行,签个到拿个分,不细讲了哈

代码:

#include<stdio.h>
//编写函数
/*********Begin*********/
int sum1(int n){
    int sum = 0;
    for(int i = 1; i <= n; i++){
        sum += i;
    }
    return sum;
}
/*********End**********/ 
int main(void)
{  
    /*********Begin*********/
    int n = 0;
    scanf("%d", &n);
    int sum = sum1(n);
    printf("%d", sum);

    /*********End**********/ 
    return 0;
}


第二关:回文数计算

本关任务:
编写函数求区间[200,3000]中所有的回文数,
回文数是正读和反读都是一样的数。如525, 1551

输出:输出区间[200,3000]中所有的回文数,一行一个回文数,不需要输出其它无关的字符。

例如: 202 212 222 232 242 …

解释:

百位数头尾数字相同,千位数头尾相同,中间俩个也得相同,就注意一下,别把位数搞错了就行

代码:

#include<stdio.h>
void solve(){
    /*********Begin*********/
    for(int i=200; i <= 999; i++){
    	int a = i/100; // 百位数字
		int b = i%100%10; // 个位数字 
		if(a == b){
			printf("%d\n",i);
		}
	}
	for(int i=1000; i <= 3000; i++){
    	int a = i/1000; // 千位数字
		int b = i/100%10; // 百位数字 
		int c = i/10%100%10; // 十位数字 
		int d = i%1000%100%10; // 个位数字 
		if(a == d && b == c){
			printf("%d\n",i);
		}
	}
	

    /*********End**********/ 
}
int main(void)
{  
    solve();
   return 0;
}

第三关:编写函数求表达式的值(秦九邵算法)

任题目描述:
有如下表达式 s = 1 + 1 / 3 + (1 * 2) / (3 * 5) + (1 * 2 * 3) / (3* 5 * 7) + … + (1 * 2 * 3 * … * n) / (3 * 5 * 7 * … * (2 * n + 1))。

编写函数求给出的n所对应的表达式s的值。

一个整数n 输出
输出表达式的值,保留小数点后10位的值。

样例输入:

4

样例输出:

1.5492063492

解释:

用秦九邵算法,就是把式子变成1+1/3(1+2/5(1+......(1+(n-1)/(2n-1)))),
从里面算到外面,数据结构里面第一章讲时间空间复杂度最常用的例子(求解多项式的值)的方法

代码:

#include<stdio.h>
//编写题目要求的函数
/*********Begin*********/
double sum1(int n){
	double sum = 1;
	if(n==1) 
	    return 1;
	else {
	for(int i = n+1; i >= 2; i--){ // 为啥是n+1呢??因为下面这个公式是用n推导的 
		sum = 1 + (double)(((i-1)*sum)/(2*i-1));
	}	
	return sum;
	}
}

/*********End**********/ 
int main(void)
{  
    /*********Begin*********/
// 1+1/3(1+2/5(1+......(1+(n-1)/(2n-1))))
    int n=0;
	double sum=0;
    scanf("%d", &n);
    sum = sum1(n);
    printf("%.10lf", sum);

    /*********End**********/ 
    return 0;
}

第4关:阶乘数列

题目描述:
求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一个数字。

一个整数n(1<=n<=20) 输出
输出表达式的值,占一行。

样例输入:

5

样例输出:

153

提示:

用int可能会溢出,需要用能表示更大范围的long long int
(注:VC6.0不支持此类型,VC下使用可使用__int64替代)

解释:

和上一题的思考完全一致,直接把式子转化成秦九邵算法的格式,
用sum = 1 + i*sum来计算

还有一种思路就是:你用一个函数计算阶乘的结果,
另一个函数里面用for循环对1-n中每个数字进行依此阶乘结果相加计算,
就是直接法,但是超级浪费时间

代码:


#include<stdio.h>
//编写函数
/*********Begin*********/
void sum1(int n){
	long long int sum = 1;
	if(n==1) 
	    printf("1");
	else {
	for(int i = n; i >= 2; i--){ 
		sum = 1 + i*sum;
	}	
	printf("%lld",sum);
	}
}
/*********End**********/ 
int main(void)
{  
    /*********Begin*********/
    int n=0;
    scanf("%d", &n);
    sum1(n);

    /*********End**********/ 
    return 0;
}



第5关:亲密数

题目描述:
两个不同的自然数A和B,如果整数A的全部因子(包括1,不包括A本身)之和等于B;
且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。
求3000以内的全部亲密数。

输入
无需输入
输出
3000以内的全部亲密数
(输出格式:(A,B),不加换行,不加分隔符号) ,一对亲密数只输出一次,小的在前

样例输出:
(220,284)(1184,1210)(2620,2924)

提示:

按照亲密数定义,要判断数a是否有亲密数,只要计算出a的全部因子的累加和为b,再计算b的全部因子的累加和为n,若n等于a则可判定a和b是亲密数。计算数a的各因子的算法:

用a依次对i(i=1~a/2)进行模运算,若模运算结果等于0,则i为a的一个因子;否则i就不是a的因子。

解释:

这个题目也不难,就是第一个你先求A的因子和B,然后再求B的因子和,
对比这个因子和是不是与A相同,是,就是亲密数;反之不然。

代码:

#include<stdio.h>
// 求因子的函数 
int sum(int n){ 
	int sum = 0;
	for(int i = 1; i <= n/2; i++){
		if(n%i == 0){
			sum += i;
		}
	}
	return sum;
}
void solve(){
    /*********Begin*********/
    for(int i = 1; i <= 3000; i++){ // i是第一个数字 
    	int b = sum(i); // b是i的因子和 
    	int c = sum(b); // c是b的因子和(c与i相同√) 
    	// c==i:确定是亲密数 
		// b!=i且b<i:不会有6 6 这种出现同时输出结果不会是bi的反向输出 
    	if(c == i && b != i && b < i){
    		printf("(%d,%d)", b,i);
		}

	}

    /*********End**********/ 
}
int main(void)
{   
    solve();
    return 0;
}


第6关:公约公倍数(不能用辗转相除)

题目描述:
写两个函数,分别求两个整数的最大公约数和最小公倍数,
用主函数调用这两个函数,并输出结果。
两个整数由键盘输入。

变量类型使用long long int。
输入
两个正整数
输出
最大公约数 最小公倍数
如果输入的数中包含负数,则输出Input Error

样例输入:

6 15

样例输出:

3 30

提示:

负数没有最大公约数和最小公倍数;
最大公约数和最小公倍数一定为正数,不可以为负数;
需要考虑代码运行效率,否则会评测超时。

解释:

开始的时候,我用的是辗转相除法,会导致时间过慢,
因为它第二个测试数字是一个long long int 型的数字,超级慢,
所以换了一个直接法,就是,从1遍历到俩个数最小的长度,看里面最大的公约数是谁,
然后最小公倍数就是俩数相乘再除以最大公约数即可。

代码:

#include<stdio.h>
//编写最大公约数GCD函数
/*********Begin*********/
 long long int  GCD(long long int a, long long int b){
	long long int max = 1;
	for(long long int i = 1; i <= a; i++){ 
		if(a%i == 0 && b%i == 0){
			max = i;
		}
	}
	return max;
	
}
/*********End**********/ 

int main(void)
{  
    long long int a,b;
    /*********Begin*********/
    scanf("%lld %lld",&a,&b);
    if(a>b){
    	long long int temp = a;
    	a = b;
    	b = temp;  	
	} // a一直小于b
	if(a<0 || b <0){
		printf("Input Error");
	}else {	
	long long int max = GCD(a,b);
	long long int min = a * b / max;
	printf("%lld %lld",max,min);
    } 
    /*********End**********/ 
    return 0;
}


【另外】
辗转相除法(但是无法通过案例,只不过就是速度慢了些)


#include<stdio.h>
//编写最大公约数GCD函数
/*********Begin*********/
int GCD(int a, int b){
	while(a%b != 0){	
	if(a<b){
		int temp = a;
		a = b;
		b = temp;
	}
	a = a%b;
    }
 //   printf("%d ",b);
    return b;
}


int main(void)
{  
    /*********Begin*********/
    int a=0, b=0;
    scanf("%d %d", &a, &b);
    int t1 = GCD(a,b);
    int t2 = a*b/t1;
    printf("%d %d", t1 ,t2);
    /*********End**********/ 
    return 0;
}
  • 16
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Bessie_Lee_gogogo

你的鼓励是我最大的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值