N皇后问题,最基础的回溯问题之一,题意简单N*N的正方形格子上放置N个皇后,任意两个皇后不能出现在同一条直线或者斜线上,求不同N对应的解。
提要:N>13时,数量庞大,初级回溯只能保证在N<=13的情况下快速得出答案,重点是数组cur[],表示的是第几行上放的皇后在第几列上,比如cur[1]=2;
表示第一行中的皇后已经放置,且在第一行的第二列上、然后用两个函数判断是否共线、下面是代码...
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cstring> using namespace std; int cur[16]; int real(int i,int j)//求i-j的绝对值 { if (i>j) return i-j; else return j-i; } int buzaitongyiahang(int i,int j) // 判断不在同一行 { for (int k=1; k<i; k++) if (cur[k]==j) return 0; return 1; } int notxie(int i,int j) //判断不在一条斜线上 { for (int k=1; k<i; k++) if (real(i,k)==real(j,cur[k])) return 0; return 1; } int putque(int n,int i) { int ans=0; int j; if (i==1) { for (j=1; j<=n; j++) { cur[i]=j; ans+=putque(n,2); cur[i]=-1; } } else if (i==n) { for (j=1; j<=n; j++) if (putque(i,j)&¬xie(i,j)) { cur[i]=j; return 1; } } else { for (j=1; j<=n; j++) if (buzaitongyiahang(i,j)&¬xie(i,j)) { cur[i]=j; ans+=putque(n,i+1); cur[i]=3276; } } return ans; } void work(int n) { for (int k=1;k<=15;k++) cur[k]=-1; printf("%d ",putque(n,1)); } int main() { int T,N; scanf("%d",&T); while (T--) { scanf("%d",&N); if (N==1) printf("1 "); else work(N); } return 0; }