题目: 输入N,有N个皇后使得它们互不攻击,即任意两个皇后都不能处在同一行、同一列或同一对角线上。
Tips : 对于windows端 , vscode 的一键格式化快捷键为shift + alt + F
对于mac端, vscode 的一键格式化的快捷键 option + shift + F
有时候,写代码时候没有很好的格式保持习惯,就可以直接快捷键,规避不清晰
定义相关的结构体
主要的是横坐标纵坐标方便后续进行栈的调用
struct Queen {
int x;
int y;
};
第一种非递归解法(c++)
由于学校里的机房在csp考试和各类考试中,电脑并没有装python的编译器,所以即便会写python,在考试写完代码后也不方便运行查看结果。所以这里就用C++写,我(小白)对vscode的编译很陌生,所以这里就用的dev c++去写的,我对在dev中代码的调试很不熟练几乎不太会用。
算法思想:非递归法就是从第二行开始,符合的情况就压栈,不符合就继续,一直尝试到最后一行,然后num数量加一,接着就是弹出来,再者去一个个试(隔了一天,这里if else 太多了,我看不清了,不知道啥情况了,脑子看晕了)
#include <iostream>
#include <stack>
#include <cmath>
using namespace std;
struct Queen { // 设立结构体,皇后所用的坐标
int x;
int y;
};
// Function to check whether the current queen's position conflicts with the queens in the stack 用来验证这个皇后的位置到底对不对
bool judgeisright(Queen a1, const stack<Queen>& q)
{
stack<Queen> temp_stack = q; // Create a copy of the stack to preserve the original
while (!temp_stack.empty()) { // Loop through all elements in the stack
Queen temp = temp_stack.top();
temp_stack.pop();
// Check for conflicts in rows, columns, and diagonals
if (a1.x == temp.x || a1.y == temp.y || abs(temp.x - a1.x) == abs(temp.y - a1.y)) {
return false;
}
}
return true;
}
//只要两个皇后在不同 的行和交叉线上 列 就返回true 说明这个位置是对的
//用于执行和判断有多少种N皇后 的问题
int workout(int N) {
stack<Queen> all;
Queen t1;
t1.x = 1;
t1.y = 1;
int num = 0;
while (t1.x <= N) { // Correct loop condition
if (t1.y <= N && judgeisright(t1, all)) {
all.push(t1);
if (t1.x == N) { // Found one solution
num++;
// Backtrack
t1 = all.top();
all.pop();
t1.y++;
} else { // Move to the first column of the next row
t1.x++;
t1.y = 1;
}
} else if (t1.y > N) { // If y is out of range, backtrack s
if (!all.empty()) {
t1 = all.top();
all.pop();
}
t1.y++;
} else {
t1.y++; // Otherwise, move to the next column
}
// If backtracking leads to an empty stack, the loop ends
if (t1.y > N && all.empty()) {
break;
}
}
return num;
}
int main() {
int N;
cout << "Please input the number of Queens you want:" << endl;
cin >> N;
cout << "There are " << workout(N) << " ways." << endl;
return 0;
}
第二种递归的解法(c++)
不断嵌套进行递归,仍然第二行开始,先把新情况的皇后摆放的位置压栈,若符合情况不冲突,就继续行数加一,继续进行递归判断,如果判断下来情况冲突,就弹出来列加一,不断重复,一直x到了N为止,然后num总情况数加一(可能大概就是这样子吧,每一列估计都要去判断一下)
#include <iostream>
#include <stack>
#include <cmath>
using namespace std;
struct Queen {
int x;
int y;
};
// Function to check whether the current queen's position conflicts with the queens in the stack
bool judgeisright(const Queen& a1, const stack<Queen>& q) {
for (stack<Queen> temp_stack = q; !temp_stack.empty(); temp_stack.pop()) {
Queen temp = temp_stack.top();
if (a1.x == temp.x || a1.y == temp.y || abs(temp.x - a1.x) == abs(temp.y - a1.y)) {
return false;
}
}
return true;
}
void workout(int x, int N, stack<Queen>& all, int& num) {
for (int y = 0; y < N; y++) {
Queen t1 = {x, y};
if (judgeisright(t1, all)) {
all.push(t1);
if (x < N - 1) {
workout(x + 1, N, all, num); // Recursive call with reference to all and num
} else {
num++; // Found a valid solution
}
all.pop(); // Backtrack
}
}
}
int main() {
int N;
cout << "Please input the number of Queens you want:" << endl;
cin >> N;
stack<Queen> all;
int num_solutions = 0;
workout(0, N, all, num_solutions); // Pass num_solutions by reference
cout << "There are " << num_solutions << " ways." << endl;
return 0;
}
运行结果应该都是没有问题的