实验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)