N皇后问题解法

这里实现的是经典回溯方法,vector数组中第i个数字X表示第i列选择X行作为i个皇后的位置。

vec[i]==vec[pos]||abs(vec[i] - vec[pos]) == abs(i - pos)主要用来判断vec数组中第pos个位置是否合法,第X和第Y个皇后位置不合法的情况下这2个二货必然在一个对角线上,垂直和水平间距相等与她们连线构成等腰直角三角形。下面是N皇后解法C++代码:

#include 
#include 
using namespace std;

void printVec(vector vec)
{
	for (int i = 0; i& vec, int pos)
{
	if (!pos) return true;
	for (int i = 0; i& vec, int pos, int &ret)
{
	if (pos >= vec.size())
	{
		++ret;
		printVec(vec);
		return;
	}
	for (int i = 0; i < vec.size(); i++)
	{
		vec[pos] = i;
		if (isValid(vec, pos))
		{
			rec(vec,pos+1,ret);
		}
	}
}
void eight_queen(int n)
{
	vector vec(n);
	int ret = 0;
	rec(vec, 0, ret);
	cout << "total num:" << ret << endl;
}
int main(int argc, char*argv[])
{
	for (int i = 1; i < 10; i++)
	{
		cout << i << "皇后解法" << endl;
		eight_queen(i);
	}
	int a = 0;
	cin >> a;
	return 0;
}

N皇后问题解法_第1张图片

听说8皇后可以10行代码写出来,代码之路果然路漫漫其修远兮,吾将继续敲代码,学算法~~

以下贴一些知乎上牛人的算法作为参考。

这个包含了递归和非递归2种方法。

N皇后问题解法_第2张图片

其他10行版本的牛人算法:

#include 
#include 
#include 
#include 
#include 
int main() {
  for (int queens[] = {0,1,2,3,4,5,6,7}; ::std::next_permutation(queens,queens+8); )
    if ((::std::bitset<15>(::std::accumulate(queens,queens+8, ::std::make_pair(0, 0), [](::std::pair a, int b){return ::std::make_pair((1<<(b+a.second))|a.first,a.second+1);}).first).count() == 8) && (::std::bitset<15>(::std::accumulate(queens, queens+8, ::std::make_pair(0, 0), [](::std::pair a, int b){return ::std::make_pair((1<<(7+b-a.second))|a.first, a.second+1);}).first).count() == 8))
      ::std::cout << queens[0] << queens[1] << queens[2] << queens[3] << queens[4] << queens[5] << queens[6] << queens[7] << ::std::endl;
}


#include 
int sum,ans[8];
int solve(int n, long long mark, int *ans){
	for (int i=n>8?++sum&0:0; n>8&&i<8; i!=7?std::cout << ans[i++] << " " : std::cout << ans[i++] << std::endl);
	for (int i=0; i<8; !(mark>>i&1)&&!(mark>>(n+i+7)&1)&&!(mark>>(n-i+30)&1)?solve(n+(ans[n-1]=i+1)-i, mark|1ll<

#include 
int queen(int l, int r, int m, int k){
    int ans = 0;
    for (int i = (~(l | r | m)) & 0xff; i; i -= i & -i)
        ans += queen((l | (i & -i)) << 1, (r | (i & -i)) >> 1 , m | (i & -i), k + 1);
    return k == 8 ? 1 : ans;
}
int main(){
    printf("%d\n", queen(0, 0, 0, 0));
}

int queens (){
    int pos[] = {0,1,2,3,4,5,6,7},ans = 0;
    while(next_permutation(pos,pos+8)){
        bool ok = true;
        for(int* p = pos;p

八皇后?十行连 N 皇后都写出来了。
int totalNQueens(int n) {
    int upperlim = (1 << n) - 1, sum = 0;
    std::function dfs = [&](int row, int l, int r) {
        if (row == upperlim) { ++sum; return; }
        for (int cur = upperlim & (~(row|l|r)), pos = 0; cur; dfs(row+pos, (l+pos)<<1, (r+pos)>>1)) {
            pos = cur & (-cur);
            cur -= pos;
        }
    };
    dfs(0, 0, 0);
    return sum;
}

#include 
int dfs(int r, int p1, int p2) {
	int ret = 0, pos = ((1<<8)-1) & ~(r|p1|p2);
	for (int k = pos & (-pos); pos; pos -= k, k = pos & (-pos))
		ret += dfs(r+k, (p1+k)<<1, (p2+k)>>1);
	return r+1 == (1<<8) ? 1 : ret;
}
int main() {
	printf("%d\n", dfs(0,0,0));
}

int queen(int points[], int size, int deep, int* success, bool check)
{
	for (int i = 0; (deep < size || (*success)++ < 0) && i < size && (points[deep] = i + deep * 8) >= 0 && (check = true); i++)
		for (int before = 0; before < deep || (check && queen(points, size, deep + 1, success, false) < 0); before++) if (points[deep] % 8 == points[before] % 8 || points[deep] == points[before] + (deep - before) * 9 || points[deep] == points[before] + (deep - before) * 7) check = false;
	return *success;
}

#include 
#define LOWBIT(x) x&(-x)
int solve(int c, int lc, int rc, int sum) {
    if(c == 0xFF) return sum + 1;
    for (int pos = ((c | lc | rc)&0xFF)^0xFF; pos; pos&=(~(LOWBIT(pos)))) {
        sum = solve(c|LOWBIT(pos), (lc|LOWBIT(pos))<<1, (rc|LOWBIT(pos))>>1, sum);
    }
    return sum;
}
int main() { printf("%d\n", solve(0, 0, 0, 0)); }

#include 

int dfs(int k=0,int n=8,int c=0,int l=0,int r=0){
	int i,mask,t,cnt=0;
	if(k==n) return 1;
	mask = c | l | r;
	for(i=0;i>1);
	}	
	return cnt;
}

int main(){
	std::cout << dfs() << std::endl;
	return 0;
}

int eight_queen(int level, int y[8], int s[15], int t[15], int r[8]) {
	if (level == 8)	return 1;
	for (int i = 0; i < 8; ++i)	if (y[i] == 0 && s[level - i + 7] == 0 && t[level + i] == 0 && (y[i] = s[level - i + 7] = t[level + i] = 1) && ((r[level] = i) || 1) && (eight_queen(level + 1, y, s, t, r)) && (y[i] = s[level - i + 7] = t[level + i] = 0));
	return 1;
}
int main() {
	int y[8] = {0}, s[15] = {0}, t[15] = {0}, r[8] = {0};
	eight_queen(0, y, s, t, r);
	return 0;
}

void DFS(unsigned row, unsigned ld, unsigned rd) {
    if (row != upperlim) {
        unsigned pos = upperlim & ~(row | ld | rd), p;
        while (pos) {
            p = pos & -pos;
            pos -= p;
            DFS(row | p, (ld | p) << 1, (rd | p) >> 1);
        }
    } else ans += 1;
}

最后再来个时间空间复杂度都为1的超级算法:
实在醉的不行....
附上知乎关于10行八皇后的连接:
http://www.zhihu.com/question/28543312

你可能感兴趣的:(N皇后问题解法)