哈工大C语言程序设计精髓 Mooc 第7章

哈工大c语言 第7章 递归

练兵区练习题

5水手分椰子(4分)

题目内容:
n(1<n<=5)个水手在岛上发现一堆椰子,先由第1个水手把椰子分为等量的n堆,还剩下1个给了猴子,自己藏起1堆。然后,第2个水手把剩下的n-1堆混合后重新分为等量的n堆,还剩下1个给了猴子,自己藏起1堆。以后第3、4个水手依次按此方法处理。最后,第n个水手把剩下的椰子分为等量的n堆后,同样剩下1个给了猴子。请用迭代法编程计算并输出原来这堆椰子至少有多少个,n的值要求从键盘输入。若输入的n值超出要求的范围,程序输出"Error!"。

  • 迭代实现
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int getMin(int input);
int main()
{	
	int input;
	printf("Input n(1<n<=5):\n");
	scanf("%d", &input);
	if(input > 5 || input <= 1){
		printf("Error!\n");
		return 0;
	}
	int res = getMin(input);
	printf("y=%d\n", res);
	return 0;
	
}

int getMin(int input){
	int index = 6;
	while(1){
		index++;
		int temp = index;
		for(int n = input;n > 0;n--){
			if((temp - 1) % input != 0) break;
			temp = temp -1 - (temp - 1) / input;
			if(n == 1) return index;
		}
	}
}
  • 递归实现
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int getMin(int input);
int judge(int current_num, int people_num, int haveDone);

int main()
{	
	int input;
	printf("Input n(1<n<=5):\n");
	scanf("%d", &input);
	if(input > 5 || input <= 1){
		printf("Error!\n");
		return 0;
	}
	int res = getMin(input);
	printf("y=%d\n", res);
	return 0;
	
}

int getMin(int input){
	int index = 6;
	while(1){
		index++;
		int temp = index;
		if(judge(index, input, input)){
			return index;
		}
		
	}
}

int judge(int current_num, int people_num, int haveDone){
	if(haveDone == 0) return 1;
	if((current_num - 1) % people_num != 0) return 0;
	return judge(current_num - 1 - (current_num - 1) / people_num, people_num, haveDone - 1);
}

6递归法计算游戏人员的年龄(4分)

题目内容:

有n个人围坐在一起,问第n个人多大年纪,他说比第n-1个人大2岁;问第n-1个人,他说比第n-2个人大2岁,…,问第3个人,他说比第2个人大2岁;问第2个人,他说比第1个人大2岁。第1个人说自己10岁,问第n个人多大年纪。

递归函数原型:unsigned int ComputeAge(unsigned int n);

  • 递归
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

unsigned int ComputeAge(unsigned int n);

int main()
{	
	unsigned int input;
	scanf("%d", &input);
	
	unsigned int res = ComputeAge(input);
	printf("The person's age is %u\n", res);
	return 0;	
}

unsigned int ComputeAge(unsigned int n){
	if(n == 1) return 10;
	return ComputeAge(n - 1) + 2;
}
  • 尾递归改进后:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

unsigned int ComputeAge(unsigned int n, unsigned int res);

int main()
{	
	unsigned int input;
	scanf("%d", &input);
	
	unsigned int res = ComputeAge(input, 10);
	printf("The person's age is %u\n", res);
	return 0;
	
}

unsigned int ComputeAge(unsigned int n, unsigned int res){
	if(n == 1) return res;
	
	return ComputeAge(n - 1, res + 2);
}

7递归法计算两个数的最大公约数(4分)

题目内容:
利用最大公约数的性质计算。对正整数a和b,当a>b时,若a中含有与b相同的公约数,则a中去掉b后剩余的部分a-b中也应含有与b相同的公约数,对a-b和b计算公约数就相当于对a和b计算公约数。反复使用最大公约数的上述性质,直到a和b相等为止,这时,a或b就是它们的最大公约数。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int Gcd(int a, int b);

int main()
{	
	int a, b;
	printf("Input a,b:");
	scanf("%d,%d", &a, &b);
	if(a <= 0 || b <= 0){
		printf("Input error!\n");
		return 0;
	}
	int res = Gcd(a, b);
	printf("%d\n", res); 
	return 0;
	
}

int Gcd(int a, int b){
	if(a == b) return a;
	else if(a > b){
		Gcd(a-b, b);
	}else{
		Gcd(a, b-a);
	}
}

8寻找中位数v1.0(4分)

题目内容:

编写一个函数返回三个整数中的中间数。函数原型为: int mid(int a, int b, int c);
函数功能是返回a,b,c三数中大小位于中间的那个数。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int mid(int a, int b, int c); 

int main()
{	
	int a, b, c;
	scanf("%d%d%d", &a, &b, &c);
	
	int res = mid(a, b, c);
	printf("The result is %d\n", res);
	return 0;
}

int mid(int a, int b, int c){
	int max = (a > b ? a : b) > c ? (a > b ? a : b) : c;
	if(a == max){
		return b>c?b:c;
	}
	else if(b == max){
		return a>c?a:c;
	}
	else {
		return a>b?a:b;
	}
}

9还原算术表达式(4分)

题目内容:
编写程序求以下算式中XYZ的值,其中两数XYZ与YZZ相加的和n(99<n<1000)的值要求从键盘输入。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int main(){
	int input;
	printf("Input n(n<1000):\n");
	scanf("%d", &input);
	for(int index = 100; index < 1000; index++){
		// 拆分
		int z = index % 10;
		int y = index % 100 / 10;
		int x = index / 100;
		int sum = 100 * (x + y)+10*(y+z)+(z+z);
		if(sum == input) {
			printf("X=%d,Y=%d,Z=%d\n", x, y, z);
			return 0;
		} 
	}
	printf("Invalid\n");
	return 0;
}

第7周编程题在线测试

1 n层嵌套平方根的计算(4分)

题目内容:

编写程序利用递归法实现如下所示n层嵌套平方根的计算

  • 递归
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

double Y (double x, int n);

int main(){
	double x;
	int n;
	printf("Please input x and n:");
	scanf("%lf,%d", &x, &n);
	
	double res = Y(x, n);
	printf("Result=%.2f\n", res); 
	return 0;
}

double Y (double x, int n){
	if(n==0) return 0;
	
	return sqrt(x + Y(x, n -1));
}
  • 尾递归
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

double Y (double x, int n, double result);

int main(){
	double x;
	int n;
	printf("Please input x and n:");
	scanf("%lf,%d", &x, &n);
	
	double res = Y(x, n, 0);
	printf("Result=%.2f\n", res); 
	return 0;
}

double Y (double x, int n, double result){
	if(n==0) return result;
	return Y(x, n - 1, sqrt(result + x));
}

2递归法求和(4分)

题目内容:

用递归方法计算如下求和计算

sum = 1 + 2 + 3 + … + n

递归函数原型:int Sum(int n);

  • 递归
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int Sum(int n);

int main(){
	int input;
	printf("Please input n:");
	scanf("%d", &input);
	if(input <= 0){
		printf("data error!\n");
		return 0;
	} 
	
	printf("sum=%d\n", Sum(input));
	return 0;
}

int Sum(int n){
	if(n == 1) return 1;
	
	return n + Sum(n - 1);
}
  • 尾递归
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int Sum(int n, int res);

int main(){
	int input;
	printf("Please input n:");
	scanf("%d", &input);
	if(input <= 0){
		printf("data error!\n");
		return 0;
	} 
	
	printf("sum=%d\n", Sum(input, 0));
	return 0;
}

int Sum(int n,int res){
	if(n == 1) return res +1;
	
	return Sum(n - 1, res + n);
}

3猴子吃桃程序_扩展3(4分)

题目内容:

猴子第一天摘了若干个桃子,吃了一半,不过瘾,又多吃了1个。第二天早上将剩余的桃子又吃掉一半,并且又多吃了1个。此后每天都是吃掉前一天剩下的一半零一个。到第n天再想吃时,发现只剩下1个桃子,问第一天它摘了多少桃子?为了加强交互性,由用户输入天数n,即假设第n天的桃子数为1。

要求采用递归法求解。

递归函数原型:int Monkey(int n, int x);

函数功能:从第n天只剩下一个桃子反向逆推出第1天的桃子数

  • 尾递归
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int Monkey(int n, int x);

int main(){
	int input;
	printf("Input days n:");
	scanf("%d", &input);
	
	
	printf("x=%d\n", Monkey(1, input));
	return 0;
}

int Monkey(int n, int x){
	if(x == 1) return n;
	
	return Monkey(2 * n + 2, x-1);
}
  • 递归
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int Monkey(int n, int x);

int main(){
	int input;
	printf("Input days n:");
	scanf("%d", &input);
	
	
	printf("x=%d\n", Monkey(1, input));
	return 0;
}

int Monkey(int n, int x){
	if(x == 0) return 0;
	
	return n + Monkey(3 * pow(2, x -2), x-1);
}

关于这道题的递归解法可能不是很好理解,我说明一下:
如果第n-1天到第n天吃了t1个,那t1等于多少呢?等于3吧
如果第n-2天到第n-2天吃了t2个,那t2等于多少呢?等于6吧
如果第n-3天到第n-3天吃了t3个,那t3等于多少呢?等于12吧

不难发现:倒数第x-1(x>0)天吃了3*2^(x-2)个

注意:当x = 2,就是倒数第一天,因为当x = 1的这一天没有吃。

4网购打折商品V2.0(5分)

题目内容:

某网上购物网站对用户实行优惠,买家购物货款p越多,则折扣越多。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int main(){
	float input, rate;
	printf("Input payment:");
	scanf("%f", &input);
	
	int scope = input / 100;
	
	if(input>=0&&input < 100) rate = 1;
	else if(input<200) rate = 0.95;
	else if(input<500) rate = 0.92;
	else if(input<1000) rate = 0.9;
	else if(input>=1000) rate = 0.85;
	
	printf("price = %.1f\n", rate * input);
	return 0;
}
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值