哈工大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;
}