1.全排列算法
全排列是数学中很常见的名词,既然有这个名词,相对应一定有这样的算法,那么如何通过程序实现这个算法呢?
下面给出了全排列的算法!
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=11;
int n,p[maxn],hash[maxn]={false};//h为散列,相关请参考散列的有关知识,p为存储当前排列中的数
void generate(int index){//求全排列的算法,整个算法可以通过图示来进行理解
if(index==n+1){
for(int i=1;i<=n;i++){
cout<<p[i]<<" ";
}
cout<<endl;
return;
}
for(int x=1;x<=n;x++){
if(hash[x]==false){
p[index]=x;
hash[x]=true;
generate(index+1);
hash[x]=false;
}
}
}
int main(){
n=3;
generate(1);
return 0;
}
2.n皇后问题
题目大意为在n*n的方格中,每一行每一列只能存在一个皇后,且这些皇后不能在同一对角线上,求这样的方案有多少种?
思路一:从n平方个方格中选取n个进行排列,然后排除,显然这种方法较为繁琐,而且很多本身就不符合题意,增大了排除的方案数,所以不是一种好的算法。
思路二:使用全排列,这样就能保证每一行每一列都只能存在一个皇后。
(1)第一种方法是先找出排列方法,再排除这些皇后不能在同一对角线上。(不是很好的算法)
(2)第二种方法是先判断已有的皇后所在的位置是否满足不在同一对角线上,先排除后进行加入皇后的位置,比较好的算法
方法一:
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=11;
int n,p[maxn],hash[maxn]={false};
int c=0;
void generate(int index){
if(index==n+1){
bool flag=true;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(abs(i-j)==abs(p[i]-p[j])){
flag=false;
}
}
}
if(flag){
c++;
return;
}
}
for(int x=1;x<=n;x++){
if(hash[x]==false){
p[index]=x;
hash[x]=true;
generate(index+1);
hash[x]=false;
}
}
}
int main(){
n=8;
generate(1);
cout<<c;
return 0;
}
方法二:
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=11;
int n,p[maxn],hash[maxn]={false};
int c=0;
void generate(int index){
void generate(int index){
if(index==n+1){
c++;
return;
}
for(int x=1;x<=n;x++){
if(hash[x]==false){
bool flag=true;
for(int pre=1;pre<index;pre++){
if(abs(index-pre)==abs(x-p[pre])){
flag=false;
break;
}
}
if(flag){
p[index]=x;
hash[x]=true;
generate(index+1);
hash[x]=false;
}
}
}
}
int main(){
n=8;
generate(1);
cout<<c;
return 0;
}
以上的方法都不能算是最优算法,只能说是一种暴力破解的方法,所以大家如果有很好的方法,欢迎留言!