一、全排列
排列与组合是常用的数学方法。
先给一个正整数 ( 1 < = n < = 10 )
例如n=3,所有组合,并且按字典序输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
AC代码:
#include<bits\stdc++.h>
using namespace std;
int path[10];
int n;
bool book[10]= {0};
void DFS(int index) {
if(index==n) {
for(int i=0; i<n-1; i++) {
cout<<path[i]<<" ";
}
cout<<path[n-1]<<endl;
return;
}
for(int i=1; i<=n; i++) {
if(!book[i]) {
path[index]=i;
book[i]=1;
DFS(index+1);
book[i]=0;//回溯,初始化
}
}
}
int main() {
cin>>n;
DFS(0);
return 0;
}
二、组合
排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r < = n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。
现要求你不用递归的方法输出所有组合。
例如n = 5 ,r = 3 ,所有组合为:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
AC代码:
#include<iostream>
#include<algorithm>
using namespace std;
int n,k;
int ans[10];
bool book[10]={0};
void DFS(int num){
if(num==k){
for(int i=0;i<k;i++)
{
cout<<ans[i]<<" ";
}
cout<<endl;
return;
}
for(int i=1;i<=n;i++){
if(book[i]==0&&i>ans[num-1]){//与全排列相比,只要加上递增顺序,就能保证没有重复
ans[num]=i;
book[i]=1;
DFS(num+1);
book[i]=0;
}
}
}
int main()
{
cin>>n>>k;
DFS(0);
return 0;
}
三、组合求和为素数
已知 n 个整数b1,b2,…,bn
以及一个整数 k(k<n)。
从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。
例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22 3+7+19=29 7+12+19=38 3+12+19=34。
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29。
AC代码:
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int n,k,num=0,sum=0;
int a[5000000];
int ans[5000000];
bool book[5000000]={0};
int Sushu(int n)
{
if(n<2){return 0;
}
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
return 0;
}
}
return 1;
}
void DFS(int index){
if(index==k){
for(int i=0;i<k;i++){
sum+=ans[i];
}
if(Sushu(sum)){
num++;
}
sum=0;
}
for(int i=0;i<n;i++){
if(!book[i]&&ans[index-1]<=a[i]){
ans[index]=a[i];
book[i]=1;
DFS(index+1);
book[i]=0;
}
}
}
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>a[i];
DFS(0);
cout<<num;
return 0;
}
四、经典n皇后
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n, tot = 0;
int col[15] = {0}, ans[15] = {0}; //col[i]的值为第i行的皇后的列数的值,即j,ans[]数组用来存放结果
bool check(int c, int r) //检查是否和已经放好的皇后冲突
{
for (int i = 0; i < r; i++)
if (col[i] == c || (abs(col[i] - c) == abs(i - r))) //因为是逐行放置,所以只考虑纵向和斜向
return false;
return true;
}
void dfs(int r,int m) //在第r行放皇后,m表示行数
{
if(r==m){ //r==m,即皇后放到最后一行,满足条件,tot++,返回;
tot++;
return;
}
for(int c=0;c<m;c++) //在此行逐列尝试
if(check(c,r)){ //检查是否冲突
col[r]=c; //不冲突就在此列放皇后
dfs(r+1,m); //转到下一行继续尝试
}
}
int main()
{
cin>>n;
for (int i = 0; i <= 13; i++) //算出所有N皇后的答案,先打表,不然会超时
{
memset(col, 0, sizeof(col)); //清空col,准备计算下一个N皇后问题
tot = 0;
dfs(0,i);
ans[i] = tot;
}
cout << ans[n] << endl;
return 0;
}