关于全排列的问题

逐渐的发现全排列是常会出现的一类问题,这里大概进行一下做题方法的总结。

我处理全排列问题主要有两种做法

1.直接用STL实现全排列 (next_permutation()函数)

 这是一个c++函数,包含在头文件里面,下面是基本格式。
 int a[];
 do{
     

 }while(next_permutation(a,a+n));

此函数返回值为bool类型

next_permutation(num,num+n)函数是对数组num中的前n个元素进行全排列,同时并改变num数组的值。

另外,需要强调的是,next_permutation()在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。

next_permutation(node,node+n,cmp)可以对结构体num按照自定义的排序方式cmp进行排序。

例:对123进行全排列:

#include 
#include 
using namespace std;
int a[3]={1,2,3};
int main()
{
    do
    {
    cout<

2.自己动手写全排列函数

例:对123进行全排列:

#include 
using namespace std;
int a[5]={1,2,3};
int vis[5];
void dfs(int k)
{
    if(k==3)
        cout<

这里附上几道例题:

1.排座位 

要安排:3个A国人,3个B国人,3个C国人坐成一排。

要求不能使连续的3个人是同一个国籍。

求所有不同方案的总数?

答案:283824

思路:9个人分别表示为1-9,然后对3取模就可以判断是否是同一国的人。

代码:

#include 
#include 
using namespace std;
int cnt=0;
int a[9]={1,2,3,4,5,6,7,8,9};
bool judge()
{
    for(int i=0;i<=6;i++)
    {
        if(((a[i]%3)==(a[i+1]%3))&&((a[i+1]%3)==(a[i+2]%3)))
            return false;
    }
    return true;
}
int main()
{
    do
    {
        if(judge())
            cnt++;
    }while(next_permutation(a,a+9));
    printf("%d",cnt);
    return 0;
}
2.看这个算式:
☆☆☆ + ☆☆☆ = ☆☆☆
如果每个五角星代表 1 ~ 9 的不同的数字。
这个算式有多少种可能的正确填写方法?
173 + 286 = 459
295 + 173 = 468
173 + 295 = 468
183 + 492 = 675
以上都是正确的填写法!
注意:
111 + 222 = 333 是错误的填写法!
因为每个数字必须是不同的! 
也就是说:1~9中的所有数字,每个必须出现且仅出现一次!
注意:
不包括数字“0”!
注意:
满足加法交换率的式子算两种不同的答案。

所以答案肯定是个偶数!

答案:336

#include 
#include 
using namespace std;
int a[9]={1,2,3,4,5,6,7,8,9};
int cnt=0;
bool judge()
{
    if(a[0]*100+a[1]*10+a[2]+a[3]*100+a[4]*10+a[5]==a[6]*100+a[7]*10+a[8])
        return true;
    return false;
}
int main()
{
    do
    {
        if(judge())
            cnt++;
    }while(next_permutation(a,a+9));
    cout << cnt << endl;
    return 0;
}

#include 
using namespace std;
int a[9]={1,2,3,4,5,6,7,8,9};
int vis[10];
int cnt=0;
bool judge()
{
    if(a[0]*100+a[1]*10+a[2]+a[3]*100+a[4]*10+a[5]==a[6]*100+a[7]*10+a[8])
        return true;
    return false;
}
void dfs(int k)
{
    if(k==9)
    {
        if(judge())
            cnt++;
        return;
    }
    for(int i=1;i<=9;i++)
    {
        if(!vis[i])
        {
            a[k]=i;
            vis[i]=1;
            dfs(k+1);
            vis[i]=0;
        }
    }
}
int main()
{
dfs(0);
    cout << cnt << endl;
    return 0;
}

你可能感兴趣的:(关于全排列的问题)