【搜索与回溯算法】有重复元素的排列问题

题目友链

题目描述

R = r 1 , r 2 , … , r n R={ r1, r2 , …, rn} R=r1,r2,,rn是要进行排列的n个小写字母。其中 r 1 , r 2 , … , r n r1, r2 , …, rn r1,r2,,rn可能相同。试设计一个算法,列出 R R R的所有不同排列。
【编程任务】
给定 n n n 以及待排列的 n n n 个小写字母。计算出这 n n n 个小写字母的所有不同排列。

输入

文件的第 1 1 1 行是字母个数 n , 1 ≤ n ≤ 500 n,1≤n≤500 n1n500。接下来的 1 1 1 行是待排列的 n n n个小写字母。

输出

计算出的 n n n个小写字母的所有不同排列,按字典序从小到大输出。最后 1 1 1行中的数是排列总数。

样例输入

4
aacc

样例输出

aacc
acac
acca
caac
caca
ccaa
6

**分析:**我觉得做这道题之前,可以先看看“全排列问题”,不要问我为什么,因为两道题特别像,基本就是沿用了“全排列问题”的思路!首先要学会字符的操作,然后就和“全排列问题”一样啦~,具体就看看注释吧!

code:

#include
using namespace std;
int a[1001],b[27],num=0,x;
char n[1001];
void s(int t){
	if(t==x+1){//判断,此处是出口
		num++;//答案数+1
		for(register int i=1;i<=t-1;++i) printf("%c",char(a[i]+'a'-1));//输出,记得对字符串进行操作,讲当前下标进行转换
		printf("\n");//记得换行
	}
	else{//如果不在出口
		for(register int i=1;i<=26;++i){
			if (b[i]>0){//判断是否标记
				a[t]=i;//存储答案
				b[i]--;//标记
				s(t+1);//进入下一层递归
				b[i]++;//回溯一步
			}
		}
	}
}
int main(){
	int k;
	char c;
	scanf("%d",&x);
	for(register int i=1;i<=x;++i){//卡常技巧
		scanf("%c",&c);
		k=c-'a'+1;//记得字符啊
		b[k]++;//标记
	}
	s(1);//从1开始搜索
	printf("%d",num);//输出
	return 0;//Van美结束
}

嗯这篇blog就到这里了,楼下隐形字,欢迎扫一扫查看↓。。。

我这么蔡,不点赞,关个注鼓励一下再走吗?

你可能感兴趣的:(DFS)