第6周中级练习

这些题都得用递归

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;
}
//和上道题差不多,深搜即可,有问题请私信
发布了28 篇原创文章 · 获赞 38 · 访问量 7181

猜你喜欢

转载自blog.csdn.net/weixin_45543556/article/details/105227133