八皇后(可以扩展为N皇后问题)
每行每列每个对角线都不允许有两个或两个以上的皇后
回溯,递归求解
#include<iostream>/// 八皇后 #include<cstdio> using namespace std; int c[10]; /// 第i行 列为a[i] int total; int n; /// 在一条主对角线上 则它们的 x-y相同 y=x+b /// 在一条负对角线上 则它们的 x+y相同 y=-x+b int v[3][100]; /// v[0]列 v[1]主对角线 v[2]负对角线 int dfs_1(int cur) // 填充第cur行 { if(cur==n){ total++; //for(int i=0;i<n;i++) // printf("%d %d\n",i,c[i]); //puts("\\\\"); } else{ for(int i=0;i<n;i++){// 列 int ok=1; for(int j=0;j<cur;j++)//行 if(c[j]==i||cur-j==i-c[j]||cur-j==c[j]-i) // 存在两元素在 同一列 或对角线 ok=0; // or if(c[j]==i||abs(cur-j)==abs(i-c[j])) if(ok){//puts("[]"); c[cur]=i; dfs_1(cur+1); } } } } /// 优化 int dfs_2(int cur) // 填充第cur行 { if(cur==n){ total++; //for(int i=0;i<n;i++) // printf("%d %d\n",i,c[i]); //puts("\\\\"); } else{ for(int i=0;i<n;i++){// 列,即第cur个皇后放在第i列上 if(!v[0][i]&&!v[1][cur-i+n]&&!v[2][cur+i]){ // 第cur行第i个列的同列,主对角线,副对角线上均没有元素 v[0][i]=v[1][cur-i+n]=v[2][cur+i]=1; c[cur]=i; dfs_2(cur+1); v[0][i]=v[1][cur-i+n]=v[2][cur+i]=0; } } } } int main() { total=0; n=8; dfs_1(0); cout<<total<<endl; total=0; dfs_2(0); cout<<total<<endl; return 0; }
回溯,非递归求解
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define MAX 100 int is(int* c,int k) { int i; for(i=1;i<k;i++) if(c[k]==c[i]||abs(i-k)==abs(c[k]-c[i])) return 0; return 1; } int main() { int c[MAX]; int N,i,j,k,case_=1; scanf("%d",&N); // N皇后 for(j=1;j<=N;j++)//初始化 c[j]=0; i=1; while(i>=1){ c[i]=c[i]+1; while(c[i]<=N&&!is(c,i)) c[i]=c[i]+1; if(i==N&&c[i]<=N){// 找到 printf("Case %d:",case_++); for(j=1;j<=N;j++) printf("% d",c[j]); puts(""); } if(i<=N&&c[i]<=N){ i+=1; } else{ c[i]=0; i=i-1; } } return 0; }
原文地址:http://blog.csdn.net/u014705854/article/details/46611039