暴力求解法 之 枚举排列

                                                                                                             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;

}


 

 

你可能感兴趣的:(枚举)