N皇后问题
最近研究N皇后问题,研究了两天两夜,根本想不明白,还被别人嫌弃我是菜鸡,真的哭出来了...
后来发现是模板有问题,太可恶了!!
现在我给大家发一下我搜集到的正确模板:
模板一:
#include<iostream> #include<stdio.h> #include<cstring> using namespace std; bool b[100], c[100], d[100]; int n, que[20], ans[20], count1; /*bool isplace(int num,int x) { for(int i = 1;i<num;i++)//到num的前num-1行无重复 { if(x == que[i])//x等于其所在列数 return false; if(abs(num - i) == abs(x - que[i])) { return false; } } return true; }*/ void dfs(int num) { if(num > n) { count1++; if(count1 > 3) return; if(count1 <= 3) { printf("%d", que[1]); for(int i = 2;i <= n;i++) { printf(" %d",que[i]); } printf("\n"); } return; } for(int i = 1; i <= n; i++) { if((!b[i]) && (!c[i+num]) && (!d[num-i+n])) { que[num] = i; b[i] = 1;//纵列 c[num + i] = 1; d[num - i + n] = 1;//两条对角线。 dfs(num + 1); b[i] = 0; c[num + i] = 0; d[num - i+n] = 0; } } return; } int main() { scanf("%d", &n); count1 = 0; dfs(1); printf("%d\n", count1); return 0; }
模板二:
#include<cstdio> #include<vector> #include<queue> #include<cstring> using namespace std; int n,k,ans; char c; bool h[10],rx[100],ry[100]; void dfs(int i) { //cout<<"i="<<i<<endl; if(i==n+1) { ans++; return; } for(int j=1;j<=n;j++) if(h[j]&&rx[j-i+10]==0&&ry[i+j]==0) { // cout<<i<<' '<<j<<endl; h[j]=0; rx[j-i+10]=1; ry[i+j]=1; dfs(i+1); rx[j-i+10]=0; ry[i+j]=0; h[j]=1; } } int main() { scanf("%d",&n); while(n) { ans=0; memset(h,1,sizeof(h)); memset(rx,0,sizeof(rx)); memset(ry,0,sizeof(ry)); dfs(1); printf("%d\n",ans); scanf("%d",&n); } return 0; } */ #include<iostream> #include<cstdio> #include<vector> #include<queue> #include<cstring> using namespace std; int n,k; long long s[11],ans; char c; bool h[11],rx[100],ry[100]; void dfs(int i,int x) { //cout<<"i="<<i<<endl; if(i==x+1) { ans++; return; } for(int j=1;j<=x;j++) if(h[j]&&rx[j-i+10]==0&&ry[i+j]==0) //对角线上的要么和相等,要么差相等 { // cout<<i<<' '<<j<<endl; h[j]=0; rx[j-i+10]=1; ry[i+j]=1; dfs(i+1,x); rx[j-i+10]=0; ry[i+j]=0; h[j]=1; } } int main() { for(int i=1;i<=10;i++) { memset(h,1,sizeof(h)); memset(rx,0,sizeof(rx)); memset(ry,0,sizeof(ry)); ans=0; dfs(1,i); s[i]=ans; } scanf("%d",&n); while(n) { printf("%lld\n",s[n]); scanf("%d",&n); } return 0; }
模板三:
#include<stdio.h> #define N 15 int n; //皇后个数 int sum = 0; //可行解个数 int x[N]; //皇后放置的列数 /* *判断函数,判断第k个皇后是否可以放在某一个位置 *如果与之前的皇后出现在同一列或同一对角线则放置失败,返回0,否则返回1 */ int place(int k) { int i; for(i=1;i<k;i++) if(abs(k-i)==abs(x[k]-x[i]) || x[k] == x[i]) return 0; return 1; } /* *求解可行解函数,当第t个皇后可以放置在t行的某一位置时,继续放置下一皇后,直到 *所有皇后放置结束,如果某一皇后不能放置,则移向下一列放置,如果这一列都不能放 *置或所有皇后放置结束,返回上一皇后重新放置,最终返回所有可行解个数。 */ int queen(int t) { if(t>n && n>0) //当放置的皇后超过n时,可行解个数加1,此时n必须大于0 sum++; else for(int i=1;i<=n;i++) { x[t] = i; //标明第t个皇后放在第i列 if(place(t)) //如果可以放在某一位置,则继续放下一皇后 queen(t+1); } return sum; } int main() { int t; scanf("%d",&n); t = queen(1); if(n == 0) //如果n=0,则可行解个数为0,这种情况一定不要忽略 t = 0; printf("%d",t); return 0; }
模板四:
#include<stdio.h> #define N 15 int n; int sum = 0; int x[N]; int place(int k) { int i; for(i=1;i<k;i++) if(abs(k-i)==abs(x[k]-x[i]) || x[k] == x[i]) return 0; return 1; } int queen() { x[1] = 0; int t=1; while(t>0) { x[t]+=1; while(x[t]<=n && !place(t)) x[t]++; if(x[t]<=n) if(t == n) sum++; else x[++t] = 0; else t--; } return sum; } int main() { int t; scanf("%d",&n); t = queen(); printf("%d",t); return 0; }
好了,这就是我研究了两天的结果,被人嫌弃菜,真的很可怜,还是继续加油吧~