题目
-
在nxn的格子里,放入N个皇后棋,并使他们相互之间无法攻击
-
皇后可攻击的方向都为“米”字型, 八方向直线攻击,如图
-
其中这是一种解决方法:
4.请输入n的数目,并返回所有可能的结果,例如如下:
input: 4
find res count: 2
[0,1,0,0
,0,0,0,1
,1,0,0,0
,0,0,1,0]
[0,0,1,0
,1,0,0,0
,0,0,0,1
,0,1,0,0]
代码
由于是NxN个格子,每一行必定有一人棋子,这里我每行都找一个可放位置,然后再递归遍历下一下行,寻找下一个可放的位置。
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <time.h>
#include <assert.h>
#include <random>
#include <tuple>
#include <list>
#include <unordered_map>
#include <memory>
class NQueen {
public:
typedef std::vector<bool> ONE_GROUP;
public:
NQueen(int count) {
m_count = count;
if (count > 0) {
m_temp_group.resize(count*count);
m_used_row.resize(count);
m_used_col.resize(count);
}
}
bool check_used(int row, int col) {
if (m_used_row[row])
return false;
if (m_used_col[col])
return false;
const int direct[] = {
1, 1, -1, -1, 1, -1, -1, 1
};
const int d_count = 8;
for (int i = 0; i < d_count; i+=2) {
int dx = direct[i];
int dy = direct[i+1];
int trow = row + dx;
int tcol = col + dy;
while (trow < m_count && tcol < m_count && trow >= 0 && tcol >= 0) {
if (m_temp_group[trow * m_count + tcol])
return false;
trow += dx;
tcol += dy;
}
}
return true;
}
void set_used(int row, int col, bool flag) {
m_used_col[col] = flag;
m_used_row[row] = flag;
m_temp_group[row * m_count + col] = flag;
}
void _try_find(int row) {
if (row >= m_count)
return;
for (int col = 0; col < m_count; ++col) {
if(check_used(row, col)){
this->set_used(row, col, true);
if (this->m_count - 1 == row) {
this->m_result.push_back(this->m_temp_group);
}
else {
this->_try_find(row + 1);
}
this->set_used(row, col, false);
}
}
}
const std::vector<ONE_GROUP>& find_all_result() {
this->m_result.clear();
std::fill(m_used_row.begin(), m_used_row.end(), false);
std::fill(m_used_col.begin(), m_used_col.end(), false);
std::fill(m_temp_group.begin(), m_temp_group.end(), false);
_try_find(0);
return m_result;
}
const std::vector<ONE_GROUP>& get_all_results() const {
return m_result;
}
int get_count() const { return m_count; }
protected:
int m_count = 4;
ONE_GROUP m_temp_group;
std::vector<ONE_GROUP> m_result;
std::vector<bool> m_used_row;
std::vector<bool> m_used_col;
};
namespace std {
std::ostream& operator<<(std::ostream& out, const NQueen::ONE_GROUP& g) {
out << "[";
if (g.size() > 0) {
auto it = g.begin();
out << *it;
++it;
int c = 1;
int count = std::sqrt(g.size());
for (; it != g.end(); ++it, ++c) {
if (c % count == 0)
out << std::endl;
out << "," << *it;
}
}
out << "]";
return out;
}
std::ostream& operator<<(std::ostream& out, const std::vector<NQueen::ONE_GROUP>& groups) {
for (auto g : groups) {
out << g << std::endl;
}
return out;
}
};
void test_n_queen() {
NQueen queen(4);
queen.find_all_result();
std::cout << "find res count:" << queen.get_all_results().size() << std::endl;
std::cout << queen.get_all_results() << std::endl;
}