【HDU - 2553】N皇后问题 (dfs经典问题,回溯,搜索)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/82424267

题干:

在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。 
你的任务是,对于给定的N,求出有多少种合法的放置方法。 
 

Input

共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。

Output

共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。

Sample Input

1
8
5
0

Sample Output

1
92
10

解题报告:

    不打表会超时的相信我、、ps:其实那个判断中,判断对角线的时候不需要判断x-n这些行,因为还没有搜索到,所以肯定不会有vis标记啊,不过这不会影响时间复杂度,只不过会使代码简洁易读一点。

AC代码:(没打表,你打一下表就好了)

#include<bits/stdc++.h>
#define mod 1010101010
#define ll long long
using namespace std;
bool vis[15][15];
int num,n;
bool fit(int x,int y) {
	//列 
	for(int i = 1; i<=n; i++) {
		if(vis[i][y]) return 0;
	}
	//主对角线
	int i = x,j = y;
	while(i>=1 && j >=1) {
		if(vis[i][j]) return 0;
		i--;j--;
	}
	i = x,j = y;
	while(i<=n && j <=n) {
		if(vis[i][j]) return 0;
		i++;j++;
	}
	//副对角线
	i = x,j = y;
	while(i>=1 && j<=n) {
		if(vis[i][j]) return 0;
		i--;j++;
	} 
	i = x,j = y;
	while(i<=n && j >= 1) {
		if(vis[i][j]) return 0;
		i++;j--;
	}
	return 1;
}
void dfs(int x) {
	if(x == n+1) {
		num++;return ;
	}
	for(int i = 1; i<=n; i++) {
		if(!fit(x,i)) continue;
		vis[x][i] = 1;
		dfs(x+1);
		vis[x][i] = 0;
	}
}
int main() 
{
	while(~scanf("%d",&n)) {
		memset(vis,0,sizeof vis);
		num = 0;
		dfs(1);
		printf("%d\n",num);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/82424267