本文結合PTA專項練習帶領讀者掌握函數,刷題為主注釋為輔,在代碼中理解思路,其它不做過多敘述。
目錄
- 6-1 計算A[n]=1/(1 + A[n-1])
- 6-2 遞歸實現順序輸出整數
- 6-3 自然數的位數(遞歸版)
- 6-4 分治法求解金塊問題
- 6-5 漢諾塔
- 6-6 重復顯示字符(遞歸版)
- 6-7 顯示平行四邊形(右)(遞歸版)
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 101int 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移到tovoid 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); // 遞歸調用,打印剩余行數的平行四邊形}
}