小记:c语言经典问题,细细想来还是 蛮耐人寻味的。
思路:对列深搜,就可以看每一列到底在哪一行 放皇后, 然后斜列上的点的坐标满足 一个等式, 用三个数组即可标记。
详情可看代码的数组解释。
代码;
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int MAX_ = 11; const int INF = 100000000; int dir[8][2] = {{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1}}; int da[2] = {0,1}; int a[]={0,1,0,0,2,10,4,40,92,352,724}; int vis[MAX_][MAX_][MAX_]; int n,m,cnt, ans; int col[MAX_];//以列为基础,看在某一列的第几行放一个皇后 int rup[2*MAX_];//从右上到左下,左上角为原点,那么从右上到左下的这一斜线上的点的坐标 x+y值相等 int lup[2*MAX_];//同理反向的斜线的坐标点 满足 n-y + x的值相等 struct point { int x,y; } s,e,t; void dfs(int i) { if(i > n){ ans++;return ; } else { for(int j =1; j <= n; j++){ if(!col[j] && !rup[i+j] && !lup[n - j + i]){ col[j] = rup[i+j] = lup[n-j+i] = 1; dfs(i+1); col[j] = rup[i+j] = lup[n-j+i] = 0; } } } } int main() { int T; char c; while(cin>>n,n) { ans = 0; memset(col,0,sizeof(col)); memset(rup,0,sizeof(rup)); memset(lup,0,sizeof(lup)); dfs(1); cout<<ans<<endl; } return 0; }