现在的位置: 首页 > 综合 > 正文

暴力求解法 之 枚举排列

2013年01月01日 ⁄ 综合 ⁄ 共 1553字 ⁄ 字号 评论关闭

                                                                                                             1、生成1~n的排列

#include<stdio.h>
#include<string.h>
const int N=1e3+10;
int a[N];
void print_permutation(int n,int *a,int cur)
{
    int i,j;
    if(cur==n) /*递归边界*/
    {
        for(i=0;i<n;i++)
           printf("%d ",a[i]);
        printf("\n");
    }
    else
    {
        for(i=1;i<=n;i++) /*尝试在a[cur]中填各种整数i*/
        {
            int ok=1;
            for(j=0;j<cur;j++)
             if(a[j]==i) /*如果i已经在a[0]~a[cur-1]出现过,则不能再选*/
             {
                 ok=0;
                 break;
             }
            if(ok)
            {
                a[cur]=i;
                print_permutation(n,a,cur+1); /*递归调用*/
            }
        }
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n))
       print_permutation(n,a,0);
    return 0;
}

                                                                                                     
2、生成可重集的排列

上面求排列的程序只适用于任意两个元素均不相同的序列,如果要求有元素相同的序列的排列时,则需要对上面的程序进行修改。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int a[N],p[N];
void print_permutation(int n,int *p,int *a,int cur)
{
    int i,j;
    if(cur==n)
    {
        for(i=0;i<n;i++)
          printf("%d ",a[i]);
        printf("\n");
    }
    else
    {
        for(i=0;i<n;i++)
         if(p[i]!=p[i-1])
         {
            int c1=0,c2=0;
            for(j=0;j<cur;j++)
              if(a[j]==p[i])
                c1++;
            for(j=0;j<n;j++)
              if(p[i]==p[j])
                c2++;
            if(c1<c2)
            {
                a[cur]=p[i];
                print_permutation(n,p,a,cur+1);
            }
         }
    }
}
int main()
{
    int n,i;
    while(~scanf("%d",&n))
    {
        for(i=0;i<n;i++)
          scanf("%d",&p[i]);
        sort(p,p+n);
        print_permutation(n,p,a,0);
    }
    return 0;
}

                                                                                                           
 3、求下一个排列

枚举所有排列的另一个方法是从字典序最小的排列开始,不停调用“求下一个排列”的过程。           如何求下一个排列呢?C++的STL中提供了一个库函数next_permutation。

#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
	int n,i,p[10];
	while(~scanf("%d",&n))
	{
		for(i=0;i<n;i++)
			scanf("%d",&p[i]);
	    sort(p,p+n); /*排序,得到p的最小排列*/
	    do
		{
			for(i=0;i<n;i++)
				printf("%d ",p[i]); /*输出排列p*/
		    printf("\n");
		}while(next_permutation(p,p+n)); /*求下一个排列*/
	}
	return 0;
}

抱歉!评论已关闭.