本文结合PTA专项练习带领读者掌握函数,刷题为主注释为辅,在代码中理解思路,其它不做过多叙述。
6-1 计算A[n]=1/(1 + A[n-1])
函数 fun 的功能是:根据整型形参 n,计算某一数据项的值。
A[1]=1, A[2]=1/(1 + A[1]), A[3]=1/(1 + A[2]), …,A[n]=1/(1 + A[n-1])
例如,若 n=10,则应输出:A10=0.617977。
函数接口定义:
float fun(int n);
其中n是用户传入的参数,函数须返回第n项的值。
裁判测试程序样例:
#include <stdio.h> float fun(int n); int main( ) { int n ; scanf("%d", &n ) ; printf("A%d=%f\n", n, fun(n) ) ; return 0; } /* 请在这里填写答案 */
输入样例:
10
输出样例:
A10=0.6180
float fun(int n) { if(n==1) return 1; else return 1/(1+fun(n-1)); }
6-2 递归实现顺序输出整数
本题要求实现一个函数,对一个整数进行按位顺序输出。
函数接口定义:
void printdigits( int n );
函数printdigits应将n的每一位数字从高位到低位顺序打印出来,每位数字占一行。
裁判测试程序样例:
#include <stdio.h> void printdigits( int n ); int main() { int n; scanf("%d", &n); printdigits(n); return 0; } /* 你的代码将被嵌在这里 */
输入样例:
12345
输出样例:
1
2
3
4
5
void printdigits( int n ) { if(n/10==0) printf("%d\n",n); else { printdigits(n/10); printf("%d\n",n%10); } }
6-3 自然数的位数(递归版)
请编写函数,求自然数的位数。
函数原型
int NumDigit(int number);
说明:参数 number 为非负整数。函数值为 number 的位数。若 number 为零,则函数值为零。
裁判程序
#include <stdio.h> int NumDigit(int number); int main() { int n; scanf("%d", &n); printf("%d\n", NumDigit(n)); return 0; } /* 你提交的代码将被嵌在这里 */
要求:不使用循环语句,用递归方法完成函数的设计。
输入样例
25173
输出样例
5
int NumDigit(int number) { if(number==0) return 0; else if(number/10==0) return 1; else { return NumDigit(number/10)+1; } }
6-4 分治法求解金块问题
分数 10
作者 张泳
单位 浙大城市学院
老板有一袋金块(共n块,2≤n≤100),两名最优秀的雇员每人可以得到其中的一块,排名第一的得到最重的金块,排名第二的则得到袋子中最轻的金块。
输入一个正整数N(2≤N≤100)和N个整数,用分治法求出最重金块和最轻金块。
本题要求实现2个函数,分别使用分治法在数组中找出最大值、最小值。
函数接口定义:
int max(int a[ ], int m, int n); int min(int a[ ], int m, int n);
递归函数max用分治法求出a[m]~a[n]中的最大值并返回。
递归函数min用分治法求出a[m]~a[n]中的最小值并返回。
裁判测试程序样例:
#include <stdio.h> #define MAXN 101 int max(int a[ ], int m, int n); int min(int a[ ], int m, int n); int main(void) { int i, n; int a[MAXN]; scanf ("%d", &n); if(n >= 2 && n <= MAXN-1 ){ for(i = 0; i < n; i++){ scanf ("%d", &a[i]); } printf("max = %d\n", max(a, 0, n-1)); printf("min = %d\n", min(a, 0, n-1)); }else{ printf("Invalid Value.\n"); } return 0; } /* 请在这里填写答案 */
输入样例:
6
3 9 4 9 2 4
输出样例:
max = 9
min = 2
int max(int a[ ], int m, int n) { int max=a[0]; for(int i=m;i<=n;i++) { if(max<a[i]) max=a[i]; } return max; } int min(int a[ ], int m, int n) { int min=a[0]; for(int i=m;i<=n;i++) { if(min>a[i]) min=a[i]; } return min; }
6-5 汉诺塔
分数 10
作者 黄龙军
单位 绍兴文理学院
汉诺(Hanoi)塔问题是一个经典的递归问题。
设有A、B、C三个塔座;开始时,在塔座A上有若干个圆盘,这些圆盘自下而上,由大到小地叠在一起。要求将塔座A上的圆盘移到塔座B上,并仍按同样顺序叠放。在移动过程中要求遵守如下规则:
每次只能移动一个圆盘; 任何时刻都不允许将较大的圆盘压在较小的圆盘之上; 在满足前两条规则的前提下,可将圆盘移至A、B、C中任何一塔座上。
例如,3个圆盘的初始状态如下:
则移动过程如下:
A->B
A->C
B->C
A->B
C->A
C->B
A->B
要求实现一个递归函数,模拟输出n(1<=n<=8)个圆盘从塔座A借助塔座C移动到塔座B上的过程(用A->B表示将圆盘从A移到B,其他类似)。
函数接口定义:
void hanoi(int n, char from, char to, char by);
其中参数 n是圆盘数 、from是原来叠放圆盘的塔座 、to是最终叠放圆盘的塔座 、by是可借助的塔座。
裁判测试程序样例:
#include<iostream> using namespace std; //将n个圆盘借助by从from移到to void hanoi(int n, char from, char to, char by); //输入n,输出将原来在A上的n个圆盘借助C移动到B上的移动过程,控制到文件尾 int main() { int n, cnt=0; while(cin>>n) { cnt++; if (cnt>1) cout<<endl; hanoi(n, 'A', 'B', 'C'); } return 0; }
输入样例:
3
4
输出样例:
A->B
A->C
B->C
A->B
C->A
C->B
A->B
A->C
A->B
C->B
A->C
B->A
B->C
A->C
A->B
C->B
C->A
B->A
C->B
A->C
A->B
C->B
void hanoi(int n, char from, char to, char by) { if(n==1) { printf("%c->%c\n",from,to); return; } else { hanoi(n-1,from,by,to); printf("%c->%c\n",from,to); hanoi(n-1,by,to,from); } }
6-6 重复显示字符(递归版)
请编写递归函数,重复显示字符。
函数原型
void Show(int number, char symbol);
说明:参数 number 为重复次数,symbol 为显示字符。函数将在屏幕上重复显示 number 个 symbol 字符。若 number ≤ 0,则不输出。
裁判程序
#include <stdio.h> void Show(int number, char symbol); int main() { int n; char s; scanf("%d %c", &n, &s); Show(n, s); putchar('\n'); return 0; } /* 你提交的代码将被嵌在这里 */
输入样例1
-3 #
输出样例1
输入样例2
5 *
输出样例2
要求:不使用循环语句。
void Show(int number, char symbol) { if(number<=0) return; else { printf("%c",symbol); Show(number-1,symbol); } }
6-7 显示平行四边形(右)(递归版)
分数 10
作者 李祥
单位 湖北经济学院
请编写递归函数,显示平行四边形(向右)。
函数原型
void RtPara(int width, int height, char symbol);
说明:参数 width、height 分别为平行四边形的底和高,symbol 为显示字符。函数将在屏幕上显示底宽为 width、高度为 height 由字符 symbol 组成的平行四边形(向右)。若 width, height ≤ 0,则不输出。
裁判程序
#include <stdio.h> void Show(int number, char symbol); void RtPara(int width, int height, char symbol); int main() { int w, h; char s; scanf("%d %d %c", &w, &h, &s); RtPara(w, h, s); putchar('\n'); return 0; } ...... /* 你提交的代码将被嵌在这里 */
提示:需要利用前面作业中的 Show 函数,此外需要增加自用的内部函数。
输入样例1
-3 0 #
输出样例1
输入样例2
20 5 *
输出样例2
******************** ******************** ******************** ******************** ********************
要求:不使用循环语句,用递归方法完成函数的设计。
关联习题:重复显示字符(递归版)。
void PrintSpaces(int number) { if(number<=0) return; else { printf(" "); PrintSpaces(number-1); } } void RtPara(int width,int height,char symbol) { if(width<=0||height<=0) return; else { PrintSpaces(height-1); // 打印平行四边形上方的空格 Show(width,symbol); // 打印平行四边形第一行 putchar('\n'); // 换行 RtPara(width,height-1,symbol); // 递归调用,打印剩余行数的平行四边形 } }