题目描述
给出一个n×nn\times nn×n的国际象棋棋盘,你需要在棋盘中摆放nnn个皇后,使得任意两个皇后之间不能互相攻击。具体来说,不能存在两个皇后位于同一行、同一列,或者同一对角线。请问共有多少种摆放方式满足条件。
输入描述:
一行,一个整数n,表示棋盘的大小。
输出描述:
输出一行一个整数,表示总共有多少种摆放皇后的方案,使得它们两两不能互相攻击。
这个题目也算是一个比较典的dfs问题,我不太会dfs。
本题就是按行去搜索,对于每次搜索,需要先判断对应的列,对角线是否能放,所以我们使用数组lie[],l[],r[]去标记同一列和统一对角线已经被访问了。对于左对角线,可以发现x-y相同,所以每次访问我们标记了l[x-y+n],加上n是为了防止出现负数。右对角线也是累死。
需要注意的是,我们搜索完下一行时,需要恢复状态。
#include<bits/stdc++.h> typedef unsigned long long ull; typedef long long ll; using namespace std; const int N = 1e3 + 10; const int mod = 1e9 + 7; /** * 不要使用#define int long long * 不开long long见祖宗 * ----YuFei Zhou */ int n; int lie[50],l[50],r[50]; //判断列/左对角线/右对角线 /** * 同一个左对角线的x-y为定值我们加n防止为负数 * 右对角线也是如此 */ int ans; void dfs(int x){ if(x > n){ ans++; return; } for (int i = 1; i <= n; ++i) { //按行去搜索 if(lie[i] == 0 && l[x-i+n] == 0 && r[x+i] == 0){ lie[i] = 1; l[x-i+n] = 1; r[x+i] = 1; dfs(x+1); //搜索下一行 lie[i] = 0; //搜索完恢复状态 l[x-i+n] = 0; r[x+i] = 0; } } } void solve(){ cin>>n; dfs(1); cout<<ans<<endl; } signed main(){ ios::sync_with_stdio(false); cin.tie(NULL),cout.tie(NULL); int t = 1; //cin>>t; while(t--){ solve();//1 2 3 4 5 } return 0 ; }