ACM_生成可重集的排序

来源:互联网 发布:手机版 淘宝 人工客服 编辑:程序博客网 时间:2024/06/07 10:39

问题要求:输入数组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]出现的次数c1for(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;}


0 0
原创粉丝点击