N皇后问题解法
来源:互联网 发布:双色球算法必中1蓝球 编辑:程序博客网 时间:2024/05/07 22:49
这里实现的是经典回溯方法,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 <iostream>#include <vector>using namespace std;void printVec(vector<int> vec){for (int i = 0; i<vec.size(); ++i){cout << vec[i] << " ";}cout << endl;}bool isValid(vector<int>& vec, int pos){if (!pos) return true;for (int i = 0; i<pos; i++){if (vec[i]==vec[pos]||abs(vec[i] - vec[pos]) == abs(i - pos)) return false;}return true;}void rec(vector<int>& 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<int> 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;}
听说8皇后可以10行代码写出来,代码之路果然路漫漫其修远兮,吾将继续敲代码,学算法~~
以下贴一些知乎上牛人的算法作为参考。
这个包含了递归和非递归2种方法。
其他10行版本的牛人算法:
#include <iostream>#include <algorithm>#include <bitset>#include <numeric>#include <utility>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<int, int> 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<int, int> 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 <iostream>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<<i|1ll<<(n+i+7)|1ll<<(n-i+30), ans):0,i++);return sum;}int main(){std::cout << solve(1, 0, ans) << std::endl;}
#include <cstdio>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<pos+8;p++) if ( count_if(pos,p,[=](int& j){return p - &j == *p-j || p - &j == j - *p ;}) ) ok = false; ans += ok; } return ans;}
八皇后?十行连 N 皇后都写出来了。int totalNQueens(int n) { int upperlim = (1 << n) - 1, sum = 0; std::function<void(int, int, int)> 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 <cstdio>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 <stdio.h>#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 <iostream>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<n;i++){t = 1<<i;if(~mask&t)cnt+=dfs(k+1,n,c|t,(l|t)<<1,(r|t)>>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
0 0
- N皇后问题解法
- N皇后问题回溯解法
- n皇后问题的解法
- n皇后问题的三种解法
- N皇后问题c语言解法
- N皇后问题的回溯解法
- n皇后问题纯数组解法
- N皇后问题的位移解法
- N皇后问题最简单解法
- N皇后问题的c++解法
- N皇后问题(回溯算法解法)
- N皇后问题的并行解法
- n皇后问题的递归解法
- n皇后 dfs解法
- n皇后解法
- N皇后问题解法及解的个数
- 使用位运输优化的n皇后问题解法
- 算法学习记录 N皇后问题 递归解法
- Codeforces 300-A/B/C
- HttpClient post 上传文件 笔记
- cognos 配置
- iOS完整学习路线图
- Activity间跳转时的效果设计,页面切换效果
- N皇后问题解法
- iOS上音频接口数据通讯(2)
- Ubuntu下samba服务器的建立
- Android64位机器内置带有32位so库的应用报错
- 安装程序无法创建新的系统分区
- Unity3d的文件读写笔记
- 利用SolrJ操作solr API完成index操作
- ABAP模块-根据销售订单创建交货单BAPI
- Python dict.has_key()方法