这些题都得用递归
1.递归插入排序(10分)
题目内容:
编写函数,对整型数组进行递归插入排序。编写函数,输入、输出数组元素。编写主函数,调用函数输入、排序、输出元素。整数个数不超过100个。
输入:在一行或多行中输入若干用空隔开的整数,输入-9999表示结束。
输出:在一行中输出整数,用一个空格隔开,末尾无空格。
输入样例:
3 2 1 5 4 -9999
输出样例:
1 2 3 4 5
时间限制:500ms内存限制:32000kb
//考插入排序,插入排序就是 把后面的数字依次插入到前面有序的序列中
//所以递归思路是 从最后一位开始,依次往前面插入
//要保证前面的序列有序,就要这样递推下去,只剩一个元素时返回
#include <iostream>
using namespace std;
void swap(int &a, int &b)
{
int t = a;
a = b;
b = t;
}
void insertSort(int a[], int len)
{
if(len==1)
return;
insertSort(a,len-1);
for(int i=len-2; i>=0; i--)
{
if(a[i+1]<a[i])//插入是通过不断与前面元素交换实现的
swap(a[i+1], a[i]);
}
}
int main()
{
int a[100];
int num;
int cnt = 0;
while(cin>>num&&num!=-9999)
a[cnt++] = num;
insertSort(a,cnt);
cout<<a[0];
for(int i=1; i<cnt; i++)
cout<<" "<<a[i];
cout<<endl;
return 0;
}
2.递归求两个数的最大公因数(10分)
题目内容:
编写函数,递归求两个整数的最大公因数。编写主函数,输入两个整数,调用函数求最大公因数,在主函数中输出。
输入:两个正整数。
输出:一个整数。
输入输出样例:
输入:
24 42
输出:
6
时间限制:500ms内存限制:32000kb
//这是辗转相除法
//取余,然后除数对余数取余,直到除数是余数的倍数
#include <iostream>
#include <cmath>
using namespace std;
int gcd(int a, int b)
{
if(a%b==0)
return b;
int mod = a%b;
gcd(b,mod);
}
int main()
{
int a, b;
cin>>a>>b;
cout<<gcd(max(a,b), min(a,b));
return 0;
}
3.全排列(10分)
题目内容:
编写递归函数,显示n个数字的全排列。例如,n=4,全排列为…………
编写主函数,输入非负整数n,调用函数显示全排列。
输入格式:一个非负整数n.
输出格式:全排列,每行一个,用一个空格隔开,末尾无空格。
输入样例:
4
输出样例:
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 3 2
1 4 2 3
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 3 1
2 4 1 3
3 2 1 4
3 2 4 1
3 1 2 4
3 1 4 2
3 4 1 2
3 4 2 1
4 2 3 1
4 2 1 3
4 3 2 1
4 3 1 2
4 1 3 2
4 1 2 3
时间限制:500ms内存限制:32000kb
话说这个oj是真的垃圾, 只支持样例那一种格式的全排列,顺序都没得换
#include <iostream>
using namespace std;
void swap(int &a, int &b)
{
int t=a;
a=b;
b=t;
}
void perm(int a[], int step, int len)
{
if(step==len)//当走到最后一格时,说明排列完成
{
cout<<a[1];
for(int i=2; i<=len; i++)
cout<<" "<<a[i];
cout<<endl;
return;
}
for(int i=step; i<=len; i++)//对每一位上的元素进行交换
{
swap(a[step], a[i]);
perm(a,step+1,len);
swap(a[step], a[i]);//尝试完成之后,要再换回来
}
}
int main()
{
int a[100];
int n;
cin>>n;
for(int i=1; i<=n; i++)
a[i] = i;
perm(a,1,n);
return 0;
}
//用深搜做出的题解过不了,只能这样做
4.递归构造可重复字符串(10分)
题目内容:
编写函数,使用递归的方法,递归地构造从顺序的m个字母中抽取n个字母组成的所有字符串。例如,从4个字母中抽取3个组成的字符串为……
输入格式:两个整数,分别表示字符数和字符串的长度,用空格隔开。数据均小于10。
输出格式:构造的字符串,每行一个,末尾无空格。
输入样例:
4 3
输出样例:
AAA
AAB
……
DDD
时间限制:500ms内存限制:32000kb
#include <iostream>
using namespace std;
char a[100];
char ch[100];
void dfs(int step, int n, int m)
{
if(step==m+1)
{
for(int i=1; i<=m; i++)
cout<<a[i];
cout<<endl;
return;
}
for(int i=1; i<=n; i++)
{
a[step]=ch[i];
dfs(step+1,n,m);
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1; i<=n; i++)
ch[i] = char('A'+i-1);
dfs(1,n, m);
return 0;
}
//这个题的顺序和深搜的顺序一样
//。。懒得写注释了,有问题请私信
5.自然数的拆分(10分)
题目内容:
给定自然数n,将其表示为若干自然数的和,输出所有的解。每组解从小到大排列。数字相同的不同排列算一组解。
输入格式:一个自然数。
输出格式:拆分式,每行一个。
输入样例:
4
输出样例:
4=1+1+1+1
4=1+1+2
4=1+3
4=2+2
4=4
时间限制:500ms内存限制:32000kb
#include <iostream>
using namespace std;
void dfs(int a[], int step, int n, const int N)
{
if(n==0)
{
cout<<N<<"="<<a[1];
for(int i=2; i<step; i++)
cout<<"+"<<a[i];
cout<<endl;
}
for(int i=1; i<=n; i++)
{
if(i>=a[step-1])
{
a[step] = i;
dfs(a,step+1,n-i,N);
}
}
}
int main()
{
int n;
int a[100]={0};
cin>>n;
dfs(a,1,n,n);
return 0;
}
//和上道题差不多,深搜即可,有问题请私信