實驗2 遞歸算法實驗
實驗內容
1. 編寫一個程序,使用遞歸算法輸出一個一維字符數組中所有字符的全排列,假設字符都不一樣。例如{‘a’,’b’,’c’}的全排列爲(a,b,c), (a,c,b), (b,a,c), (b,c,a), (c,a,b), (c,b,a)。
源代碼:
#include<bits/stdc++.h>
using namespace std;
char s[500],ans[500];
int v[500], len, sum;
void dfs(int k)
{
if(k == len){
printf("%s\n",ans);
return ;
}
for(int i=0; i<len; i++){
if(!v[i]){
ans[k] = s[i];
v[i] = 1;
dfs(k+1);
v[i] = 0;
}
}
}
int main()
{
cin >> s;
len = strlen(s);
sort(s,s+len);
dfs(0);
}
- 九數組分數。1, 2, 3…9 這九個數字組成一個分數,其值恰好爲1/3,如何組合?編寫程序輸出所有的組合。
源代碼:
#include<bits/stdc++.h>
using namespace std;
int a[500];
int v[500];
void dfs(int k)
{
if(k == 10){
if((a[1]*1000+a[2]*100+a[3]*10+a[4])*3 == a[5]*10000+a[6]*1000+a[7]*100+a[8]*10+a[9] ){
printf("%d%d%d%d / %d%d%d%d%d = 1/3\n",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
return ;
}
}
for(int i=1; i<=9; i++){
if(!v[i]){
a[k] = i;
v[i] = 1;
dfs(k+1);
v[i] = 0;
}
}
}
int main()
{
dfs(1);
}
5823 / 17469 = 1/3
5832 / 17496 = 1/3
- 使用遞歸編寫一個程序,逆序輸出一個正整數。例如輸入1234,輸出4321。
源代碼:
#include<bits/stdc++.h>
using namespace std;
int a;
void print(int a)
{
if(a){
printf("%d",a%10);
print(a/10);
}
}
int main()
{
cin >> a;
print(a);
}
- 使用遞歸編寫一個程序,計算一個正整數中所有數字之和。例如輸入234,輸出9。
源代碼:
#include<bits/stdc++.h>
using namespace std;
int a, sum = 0;
void print(int a)
{
if(a){
sum += a%10;
print(a/10);
}
}
int main()
{
cin >> a;
print(a);
printf("%d\n",sum);
}
- 使用遞歸編寫一個程序,求一個正整數n的所有劃分個數。例如,輸入3,輸出3;輸入4,輸出5。
源代碼:
#include<bits/stdc++.h>
using namespace std;
int n, m;
int fun(int n, int m)
{
if(n<1 || m<1) return 0;
if(n==1 || m==1) return 1;
if(n < m) return fun(n, n);
if(n == m) return fun(n, m-1) + 1;
return fun(n, m-1) + fun(n-m, m);
}
int main()
{
cin >> n;
cout << fun(n, n) ;
}
6. 編寫一個遞歸函數,返回一個字符串中大寫字母的數目。例如,輸入“AbcD”,輸出2。
源代碼:
#include<bits/stdc++.h>
using namespace std;
int a, sum = 0;
string s;
void cal(string s, int k)
{
if(k == s.size()) return ;
if(isupper(s[k])) sum++;
cal(s,k+1);
}
int main()
{
cin >> s;
cal(s,0);
printf("%d\n",sum);
}
- 使用遞歸編寫一個程序實現漢諾塔問題,要求在輸入圓盤數量之後,輸出圓盤的移動步驟,輸出格式示例如下:
第1步:1號盤從A柱移至B柱
第2步:2號盤從A柱移至C柱
……
源代碼:
#include<bits/stdc++.h>
using namespace std;
int n, sum = 0;
int i=1;
void move(int n, char st, char ed)
{
printf("第%d步:%d號盤從%c柱移至%c柱\n",i,n,st,ed);
}
void hanoi(int n, char st, char m, char ed)
{
if(n == 0);
else{
hanoi(n-1, st, ed, m);
move(n, st, ed);
i++;
hanoi(n-1, m, st, ed);
}
}
int main()
{
cin >> n;
char a = 'A',b='B',c='C';
hanoi(n,a,b,c);
}
當圓盤數量爲4時,詳細移動步驟爲:
4
第1步:1號盤從A柱移至B柱
第2步:2號盤從A柱移至C柱
第3步:1號盤從B柱移至C柱
第4步:3號盤從A柱移至B柱
第5步:1號盤從C柱移至A柱
第6步:2號盤從C柱移至B柱
第7步:1號盤從A柱移至B柱
第8步:4號盤從A柱移至C柱
第9步:1號盤從B柱移至C柱
第10步:2號盤從B柱移至A柱
第11步:1號盤從C柱移至A柱
第12步:3號盤從B柱移至C柱
第13步:1號盤從A柱移至B柱
第14步:2號盤從A柱移至C柱
第15步:1號盤從B柱移至C柱
8. 一次大型派對的最後節目是選出一位幸運人士,該人士將獲得派對組織者準備的一個鑽石戒指。而選擇幸運人士的辦法是讓所有人員一字排列,然後從左至右點數,凡是奇數號的全部剔除。對於剩下的人員,又從左至右點數,逢奇數號就剔除。如此不斷遞歸下去,直到只剩下一個人爲止,此人即爲幸運之人。請設計一個遞歸算法計算幸運之人所在的位置並分析該算法的時間複雜度。
源代碼:
#include<bits/stdc++.h>
using namespace std;
int n;
int fun(int n)
{
if(n==1)
return 1;
return fun(n/2)*2;
}
int main()
{
cin >> n;
cout << fun(n) ;
}
時間複雜度分析:
時間複雜度:O(n)