n后问题

n后问题

    在n*n的棋盘上放置彼此不受攻击的n个皇后,按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n*n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。


样例输入

7
8

样例输出

40
92

解法1(暴力):

n个皇后放置于n*n的矩阵中,有n*n种方式 
利用 n 进制,进行每个皇后放置
每一行一定出现一个皇后,用x[j]数组存放 第 j 行的 皇后放置的列数
所以此时 i 换成n位 n 进制之后赋值给 x 数组
对每种情况进行列与对角线的判断。


#include <stdio.h>
#include <string.h>
#include <math.h>

int n;
int x[100];

int main()
{
	scanf("%d",&n);
	int count=0;
	for(int i=0;i<pow(n,n);i++)
	{
		int j=i;
		int flag=1;
		for(int a=0;a<n;a++)
		{
			x[a]=j%n;
			j/=n;
		}
		for(int z=0;z<n;z++)
		{
			for(int k=0;k<z;k++)
			{
				if(x[z]==x[k] || (fabs(k-z)==fabs(x[k]-x[z])))
					flag=0;
			}
		}
		if(flag==1)
			count++;
	}
	printf("%d\n",count);
	return 0;
}



解法2(回溯):


要求同一行、同一列、对角线上没有两个皇后存在
所以每一行一定出现一个皇后,用x[i]数组存放 第 i 行的 皇后放置的列数
所以,此时可以对 x 数组的每一位进行回溯,当 t==n 时代表 n 个皇后已经放置完毕 
因为在放置皇后的过程中已经进行判断,所以此时已经不可能出项不符合规定的情况。
方案数直接进行自加即可。

因为x[i]中存放皇后出现的列数,所以判断是否满足情况的时候,不需要判断一行是否有两个皇后,
每放置一个皇后,进行判断此处是否能放置,
此时对角线的判断已经变成:   fabs(k-i)==fabs(x[k]-x[i])


#include <stdio.h>
#include <string.h>
#include <math.h> 
int n;
int x[100];
int count=0;

bool ok(int k)
{
	for(int i=0;i<k;i++)
	{
		if(x[i]==x[k] || (fabs(k-i)==fabs(x[k]-x[i])))
			return false;
	 } 
	 return true;
} 

void dfs(int t)
{
	if(t==n)
	{
		count++;
		return;
	}
	for(int i=0;i<n;i++)
	{
		x[t]=i;
		if(ok(t))
			dfs(t+1);
	}
}
int main()
{
	scanf("%d",&n);
	dfs(0);
	printf("%d\n",count);
	return 0;
}


### 解决N皇后问题回溯法 N皇后问题是一个经典的回溯算法问题,它要求在N×N的棋盘放置N个皇后,使得它们之间不能相互攻击。解决这个问题的关键在于使用回溯算法逐步尝试不同的放置位置,并在发现不满足条件时回溯到上一步,来找到所有可能的解。 #### 回溯法实现 回溯法的基本思路是从棋盘的第一行开始,尝试在每一行中选择一个位置放置一个皇后,并检查该位置是否其他已经放置皇后冲突。如果冲突,则回溯到上一行,尝试另一个位置。如果当前行成功放置了一个皇后,则继续在下一行中放置皇后,直到所有N个皇后都被放置棋盘上。 以下是一个使用回溯法解决N皇后问题的Python实现: ```python def solve_n_queens(n): def is_not_under_attack(row, col): for i in range(row): if board[i] == col or \ board[i] - i == col - row or \ board[i] + i == col + row: return False return True def place_queen(row): if row == n: solutions.append(board[:]) return for col in range(n): if is_not_under_attack(row, col): board[row] = col place_queen(row + 1) solutions = [] board = [-1] * n place_queen(0) return solutions ``` 在这个实现中,`board`数组用来记录每一行皇后放置的列位置。`is_not_under_attack`函数用来检查当前位置是否其他已经放置皇后冲突。`place_queen`函数递归地在每一行放置皇后,并收集所有有效的解。 #### 位运算优化 对于较大的N值,可以使用位运算来优化回溯法的性能。这种方法利用位运算快速检查当前位置是否其他已经放置皇后冲突。 以下是一个使用位运算优化的N皇后问题解法: ```cpp #include <iostream> #include <vector> using namespace std; class Solution { public: vector<vector<string>> solveNQueens(int n) { vector<vector<string>> res; vector<int> pos(n, -1); helper(0, n, pos, res); return res; } void helper(int row, int n, vector<int>& pos, vector<vector<string>>& res) { if (row == n) { vector<string> solution(n, string(n, '.')); for (int i = 0; i < n; ++i) { solution[i][pos[i]] = 'Q'; } res.push_back(solution); return; } for (int col = 0; col < n; ++col) { if (isValid(row, col, pos)) { pos[row] = col; helper(row + 1, n, pos, res); pos[row] = -1; } } } bool isValid(int row, int col, vector<int>& pos) { for (int i = 0; i < row; ++i) { if (pos[i] == col || abs(row - i) == abs(col - pos[i])) { return false; } } return true; } }; ``` 在这个实现中,`pos`数组记录每一行皇后放置的列位置。`isValid`函数检查当前位置是否其他已经放置皇后冲突。`helper`函数递归地在每一行放置皇后,并收集所有有效的解。 ### 相关问题 1. 如何使用回溯法解决N皇后问题? 2. 位运算如何优化N皇后问题的解法? 3. N皇后问题的解法有哪些经典算法实现? 4. 如何生成N皇后问题的所有可能解? 5. N皇后问题的解法如何扩展到更大的棋盘
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值