- 前些天好奇去百度了一下algorithm的函数库,偶然发现还要全排列这种好东西
这就给我们解决某些问题提供了很大的方便了
下面有请我们的主角登场next_permutation函数
这个函数就是将你给定的序列之后的排列全排出来
后来看到还有pre_permutation函数
是将之前的序列全排
下面上一道例题用两种方法来写:
Description
输出N个数的无重复全排列
Input
输入一个数值N
1<=N=50
Output
输出N个数的无重复全排列,每个数之间用空格隔开
最后一行输出无重复全排列的个数。
Sample Input Copy
3
Sample Output Copy
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Total=6
第一种是dfs的不断的递归思想来完成
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int n;
int vis[11] = {0} ;//访问数组
int numth[11] ;
void dfs(int x)
{
int i;
if(x>n) //x大于n时输出,不能等于,等于时numth[n]还没被赋值
{
for(i=1;i<=n;i++)
cout<<numth[i]<<" ";
cout<<endl;
}
for(i=1;i<=n;i++)
{
if(!vis[i]) //判断是否被访问
{
vis[i] = 1;
numth[x] = i;
dfs(x+1);
vis[i] = 0; //回溯
}
}
}
int main()
{
while(cin>>n)
{
memset(vis,0,sizeof(vis));//访问数组置0
dfs(1); //数组numth[]从1开始遍历,注意不是0
}
return 0;
}
第二种便使用了next_permutation函数
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn=1005;
int a[maxn];
int main()
{
int n,num=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
a[i]=i+1;
do
{ for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
num++;
}while(next_permutation(a,a+n));
printf("Total=%d",num);
return 0;
}
把1~N这N个整数摆成一个环,要求任意相邻两个数的和为素数。按字典序打印出以1开始的素数环
Input
一个整数N (<=10)
Output
每行一个素数环。每个数之间用一个空格隔开。
无解输出 No Solution
Sample Input Copy
4
Sample Output Copy
1 2 3 4
1 4 3 2
今天再次再这种题目上用到了next_permutation 函数
具体代码如下:
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn=1005;
int a[maxn];
int main()
{
int n,num=0,m,flag1=0,p;
scanf("%d",&n);
for(int i=0;i<n;i++)
a[i]=i+1;
do
{ int flag=1,b=0;
for(int i=0;i<n-1;i+=1)
{
m=a[i]+a[i+1];
p=a[0]+a[n-1];
for(int i=2;i<m;i++){
if(m%i==0||p%i==0&&p!=i){
b++; // 素数个数加1
}
}}
if(b==0)
flag=0;
if(!flag)
{
for(int i=0;i<n;i++)
if(a[0]==1)
{
printf("%d ",a[i]);
flag1=1;
}
if(a[0]==1)
printf("\n");
}
}while(next_permutation(a,a+n));
if(!flag1)
printf("No Solution");
return 0;
}