您的位置:首页 > 产品设计 > UI/UE

LeetCode 50 51 N-Queens (启发式搜索)

2018-03-19 16:20 162 查看

LeetCode 51 52 N-Queens (启发式搜索)

Description



51 返回所有方案

52 返回方案数

代码

51

class Solution {
public:
int N;
vector<vector<string>> solutions;

// 皇后类
struct Queen {
// 皇后在棋盘上的位置坐标
int x, y;

Queen(int x = 0, int y = 0) : x(x), y(y) {};

// 重载判等操作符,以检测不同皇后之间可能的冲突
bool operator==(Queen const &q) const {
return (x == q.x)        // 行冲突(这一情况其实并不会发生,可省略)
|| (y == q.y)        // 列冲突
|| (x + y == q.x + q.y)    // 沿正对角线冲突
|| (x - y == q.x - q.y);    // 沿反对角线冲突
}

// 重载不等操作符
bool operator!=(Queen const &q) const {
return !(*this == q);
}
};

// 打印
void printboard(const vector<Queen> &solu) {
vector<string> solution;
int pos = 0;
for (int i = 0; i < N; i++) {
string l;
for (int j = 0; j < N; j++) {
if (solu[pos].x == i && solu[pos].y == j)
l+='Q', pos++;
else
l+='.';
}
solution.emplace_back(l);
}
solutions.emplace_back(solution);
}

vector<vector<string>> solveNQueens(int n) {
N = n;
// 存放(部分)解的栈
vector<Queen> solu;
// 从原点位置出发
Queen q(0, 0);

do {
// 若已出界,则回溯一行,并继续试探下一列
if (N <= solu.size() || N <= q.y) {
q = solu.back();
solu.pop_back();
q.y++;
}
// 否则,试探下一行
else {
// 通过与已有皇后的比对
while (q.y < N) {
bool found = false;
for (int i = 0; i < solu.size(); i++)
if (solu[i] == q) {
found = true;
break;
}
if (found) {
q.y++;
} else
break;
}
// 若存在可摆放的列
if (N > q.y) {
// 则摆上当前皇后
solu.push_back(q);
// 若部分解已成为全局解,则通过全局变量nSolu计数并打印
if (N <= solu.size()) {
printboard(solu);
}
q.x++;
q.y = 0;// 转入下一行,从第0列开始,试探下一皇后
}
}
} while ((0 < q.x) || (q.y < N));
// 所有分支均已或穷举或剪枝之后,算法结束
return solutions;
}
};




52

class Solution {
public:
int nSolu;

// 皇后类
struct Queen {
// 皇后在棋盘上的位置坐标
int x, y;

Queen(int x = 0, int y = 0) : x(x), y(y) {};

// 重载判等操作符,以检测不同皇后之间可能的冲突
bool operator==(Queen const &q) const {
return (x == q.x)        // 行冲突(这一情况其实并不会发生,可省略)
|| (y == q.y)        // 列冲突
|| (x + y == q.x + q.y)    // 沿正对角线冲突
|| (x - y == q.x - q.y);    // 沿反对角线冲突
}

// 重载不等操作符
bool operator!=(Queen const &q) const {
return !(*this == q);
}
};

int totalNQueens(int N) {
nSolu = 0;
// 存放(部分)解的栈
vector<Queen> solu;
// 从原点位置出发
Queen q(0, 0);

do {
// 若已出界,则回溯一行,并继续试探下一列
if (N <= solu.size() || N <= q.y) {
q = solu.back();
solu.pop_back();
q.y++;
}
// 否则,试探下一行
else {
// 通过与已有皇后的比对
while (q.y < N) {
bool found = false;
for (int i = 0; i < solu.size(); i++)
if (solu[i] == q) {
found = true;
break;
}
if (found) {
q.y++;
} else
break;
}
// 若存在可摆放的列
if (N > q.y) {
// 则摆上当前皇后
solu.push_back(q);
// 若部分解已成为全局解,则通过全局变量nSolu计数并打印
if (N <= solu.size()) {
nSolu++;
}
q.x++;
q.y = 0;// 转入下一行,从第0列开始,试探下一皇后
}
}
} while ((0 < q.x) || (q.y < N));
// 所有分支均已或穷举或剪枝之后,算法结束
return nSolu;
}
};


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  N皇后 启发式搜索