ACM_生成可重集的排序

问题要求:输入数组P,并按字典序输出数组A个元素的全排列。

问题来源:刘汝佳大白皮P185


Code:

/*
*	Note: 
*		序列A 一次全排列 
*		序列P 需要进行全排列的数组
*		分析:1~n的全排列easy,用递归实现,这个也是相同的方法,但是在处理出现重复数字的时候会出现问题
*	例如 in:1 1 1 , out:sum=27,这很明显是错的,为什么错,因为每个1都当成与其他1不想同的数来处理了,如 
*	何解决这个问题?首先统计出现在数组A中出现的1的次数是否和数组P中的1的数目相同,如果不同则继续递归。 
* 	这样解决了对3个1都进行排序的问题,但是还没有解决"重复"的问题,i代表数组P的下标,如果数组P中前后两个
*	元素是相同的,那自需要进行一次操作。但是如果输入的是 1 2 1,结果还是出错,为什么?因为数组P是个 
*	无序的数组,所以先对其进行一下排序就能完成所要求的操作了。 
*/
#include<algorithm> 
#include<cstdio>
using namespace std;
int sum;

void print_permutation(int n,int* A,int cur,int* P){	//cur相当于step 
	if(cur==n){					//递归边界 
		for(int i=0;i<n;i++)	printf("%d ",A[i]);
		printf("\n");
		sum++;
		return;
	}
	for(int i=0;i<n;i++){		//尝试在A[cur]中填各种整数P[i] 
		if(!i||P[i]!=P[i-1]){
			int  c1=0,c2=0;			
			for(int j=0;j<cur;j++)	if(A[j]==P[i])	c1++;	//c1是A[0]~A[cur-1]中P[i]出现的次数c1
			for(int j=0;j<n;j++)	if(P[j]==P[i])	c2++;	//c2是P数组中P[i]出现的次数 
			if(c1<c2){
				A[cur]=P[i];
				print_permutation(n,A,cur+1,P);	//向下递归 
			} 
		}
	} 
} 
int main(){
	int A[1000],n,P[1000];
	while(scanf("%d",&n)!=EOF){
		sum=0;
		for(int i=0;i<n;i++)
			scanf("%d",&P[i]);
		sort(P,P+n); 
		print_permutation(n,A,0,P);
		printf("sum = %d\n",sum);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值