排列类枚举(递归)

发布于:2024-04-27 ⋅ 阅读:(26) ⋅ 点赞:(0)

全部排列问题

题目描述:输出 1…n 个数的全部排列。全部排列中,数字可以重复 。 例如输入 3 输出全部排列的结果如下:1

11、112、113、121、122、123、131、132、133、211、212、213、221、 222、223、231、232、233、311、312、313、321、322、323、331、332、333。

输入 一个整数 n(1<=n<=6) 输出 1按照由小到大的顺序输出 1…n 这 n 个数的全部排列情况。

输入复制

2

输出复制

11

12

21

22

#include<bits/stdc++.h>
using namespace std;
void func(int,int);
int a[110]={0};
int main()
{
	int n;
	cin>>n;
	func(n,0);
	
	
	return 0;
}
void func(int n,int k)
{
	if(k>=n)
	{
		for(int i=0;i<k;i++)cout<<a[i];
		cout<<endl;
		return;
	}
	for(int i=1;i<=n;i++)
	{
		a[k]=i;
		func(n,k+1);
	}
}

全排列的结果

题目描述:从键盘读入一个整数 n,请输出 1∼n 中所有整数的全排列,按照由小到大输出结果,每组的 n 个数之 间用空格隔开。

全排列的含义:从 n 个不同元素中任取 m (m≤n)个元素,按照一定的顺序排列起来,叫做从 n 个 不同元素中取出 m 个元素的一个排列。当 m=n 时所有的排列情况叫全排列。

如当 n=3 时,全排列的结果为:

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

输入 一个整数 n(≤1≤n≤6); 输出 1∼n 中所有数的全排列的结果,按照由小到大输出,每行 n 个数。

#include<bits/stdc++.h>
using namespace std;
void func(int,int);
int a[110]={0};
int b[110]={0};
int main()
{
	int n;
	cin>>n;
	func(n,0);
	
	return 0;
}
void func(int n,int k)
{
	if(k>=n)
	{
		for(int i=0;i<k;i++)cout<<a[i]<<" ";
		cout<<endl;
		return;
	}
	for(int i=1;i<=n;i++)
	{
		if(b[i]==0)
		{
			a[k]=i;
			b[i]=1;
			func(n,k+1);
			b[i]=0;
		}
	}
}

n个数的全排列

题目描述: 从键盘读入 n 个整数(每个数都是 1∼9 之间的数),输出这 n 个整数的全排列(数字不能 重复)。 输入 第 1 行输入一个整数 n。(1≤n≤8) 第 2 行输入 n 个不相等的整数。(每个数在 [1,9] 的范围内) 输出 输出若干行,每行包括 n 个数据,表示一种排列方案,所有的排列按字典码从 小到大排序输出。 样例

输入复制

3

4 6 2

输出复制

2 4 6

2 6 4

4 2 6

4 6 2

6 2 4

6 4 2

#include<bits/stdc++.h>
using namespace std;
void func(int,int);
int a[110]={0};
int b[110]={0};
int c[110]={0};
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>b[i];
	}
	func(n,0);
	
	
	return 0;
}
void func(int n,int k)
{
	if(k>=n)
	{
		for(int i=0;i<k;i++)cout<<a[i]<<" ";
		cout<<endl;
		return;
	}
	for(int i=1;i<=n;i++)
	{
		if(b[i]==0)
		{
			a[k]=c[i];
			b[i]=1;
			func(n,k+1);
			b[i]=0;
		}
	}
}

n个数取出r个数排列

题目描述:从 1∼n 任意挑出 r 个数进行排列,请从小到 大输出所有可能的排列结果。

如:n=5,r=2,则输出结果如下

1 2

1 3

1 4

1 5

2 1

2 3

2 4

2 5

3 1

3 2

3 4

3 5

4 1

4 2

4 3

4 5

5 1

5 2

5 3

5 4 

输入 两个整数 n 和 r ( n 和 r 都是 3∼6 之间的整数) 输出 从 1∼n 中取出 r 个数的排列结果!

#include<bits/stdc++.h>
using namespace std;
void func(int,int);
int a[110]={0};
int b[110]={0};
int r;
int main()
{
	int n;
	cin>>n>>r;
	func(n,0);
	
	
	return 0;
}
void func(int n,int k)
{
	if(k>=r)
	{
		for(int i=0;i<k;i++)cout<<a[i]<<" ";
		cout<<endl;
		return;
	}
	for(int i=1;i<=n;i++)
	{
		if(b[i]==0)
		{
			a[k]=i;
			b[i]=1;
			func(n,k+1);
			b[i]=0;
		}
	}
}

谷仓的保安

题目描述:Farmer John给谷仓安装了一个新的安全系统,并且要给牛群中的每一个奶牛安排一个有效的密码。

组成一个有效的密码要遵守以下条件:

1.由 L (3≤L≤15)个小写字母(来自传统的拉丁字母集'a'...'z')组成。

2.至少有一个元音('a', 'e', 'i', 'o', 'u')。

3.至少两个辅音 (除去元音以外的音节)。

4.有按字母表顺序出现的字母(例如,'abc'是有效的,而'bac'不是) 。

给定一个期望长度 L 和 C 个小写字母,写一个程序,打印出所有的长度为 L、能由这些字母组成的有效密码。密码必须按字母表顺序打印出来,一行一个。 输入 第一行: 两个由空格分开的整数,L 和 C 。(3≤C≤26) 第二行: C 个空格分开的小写字母,密码是由这个字母集中 的字母来构建的。 输出 输出若干行,每一个输出行包括一个长度为 L 个字符的密 码(没有空格)。输出行必须按照字母顺序排列。 如果计算出超过 25000 个有效密码,你的程序只需输出前 25000 个有效密码,即使后面还存在有效密码。

输入复制

4 6

a t c i s w

输出复制

acis

acit

aciw

acst

acsw

actw

aist

aisw

aitw

astw

cist

cisw

citw

istw

#include<bits/stdc++.h>
using namespace std;
void func(int,int);
char a[110]={'\0'};
int b[110]={0};
char c[110]={'\0'};
int cnt=0;
int s;
int main()
{
	int l;
	cin>>l>>s;
	for(int i=0;i<s;i++)
	{
		cin>>c[i];
	}
	sort(c+0,c+s);//把此数组按字典顺序重新排列 
	func(l,0);
	
	
	return 0;
}
void func(int l,int k)
{
	if(k>=l)
	{
		if(cnt<25000)
		{
			cnt++;
			bool sss=false;
			int cnt2=0;
			for(int i=0;i<l;i++)
			{
				if(a[i]=='a'||a[i]=='e'||a[i]=='i'||a[i]=='o'||a[i]=='u')sss=true;
				else cnt2++;
				if(a[i]>a[i+1]&&i+1<l)
				{
					sss=false;
					break;
				}
				if(cnt2>=2&&sss==true)break;
			}
			if(sss==false||cnt2<2)return;
			for(int i=0;i<k;i++)cout<<a[i];
			cout<<endl;
		}
		return;
	}
	for(int i=0;i<s;i++)
	{
		if(b[i]==0)
		{
			a[k]=c[i];
			b[i]=1;
			func(l,k+1);
			b[i]=0;
		}
	}
	return;
}

三个三位数

题目描述: 将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数构成 1:2:3的比例,试 求出所有满足条件的三个三位数。 例如:三个三位数192,384,576满足以上条件。 输入 无。 输出 每行三个三位数,为满足条件的一种方案。这三个三位数按从小到大的方式给出,相邻两个数之间 用单个空格隔开。 请按照第一个三位数从小到大的顺序依次输出每种方案

#include<bits/stdc++.h>
using namespace std;
void func(int,int);
int a[110]={1,2,3,4,5,6,7,8,9};
int b[110]={0};
bool c[110];
int main()
{
	func(9,0);
	
	
	return 0;
}
void func(int n,int k)
{
	if(k>n-1)
	{
		int aaa=b[0]*100+b[1]*10+b[2];
	    int bbb=b[3]*100+b[4]*10+b[5];
	    int ccc=b[6]*100+b[7]*10+b[8];
	    if(aaa*2==bbb&&aaa*3==ccc)cout<<aaa<<" "<<bbb<<" "<<ccc<<endl;
	    return;
	}
	for(int i=1;i<=9;i++)
	{
		if(c[i]==0)
		{
			c[i]=1;
			b[k]=i;
			func(n,k+1);
			c[i]=0;
		}
	}
}

简单单词接龙

题目描述:有 n 个单词( 1≤n≤50 ),每个单词由 2 个小写字母组成,并约定第 1 个单词为龙头。

例如:n=8。

8 个单词为:

aa、ac、ab、de、bh、hk、cd、af

接龙的方法为前一个单词的第 2 个字母和后一个单词的第 1 个字符相同 此时,可接的方法有: aa-ac-cd-de 长度为 4 ,即龙上有 4 个单词。 也可以接:aa-ab-bh-hk,长度为 4 。 还可以接:aa-af,长度为 2。 程序要求给出单词之后,求出最长龙的长度。

输入复制

7

aa

ac

ab

de

bh

hk

cd

输出复制

4

#include<bits/stdc++.h>
using namespace std;
void func(int,int);
string a[110];
bool b[110];
string c[110];
int cnt=0;
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	}
	func(n,0);
	cout<<cnt;
	
	
	return 0;
}
void func(int n,int k)
{
	if(k>=n)return;
	for(int i=0;i<n;i++)
	{
		if(k==0)
		{
			c[k]=a[0];
			b[0]=1;
			cnt=max(cnt,k+1);
			func(n,k+1);
			b[0]=0;
		}
		else if(c[k-1][1]==a[i][0]&&b[i]==0)
		{
			c[k]=a[i];
			b[i]=1;
			cnt=max(cnt,k+1);
			func(n,k+1);
			b[i]=0;
		}
	}
}