64-八皇后问题
2018-03-26 22:31
113 查看
问题描述:
努比亚和苏丹没有子女,所以他要从一些有集成资格的继承者中挑选一个出来继承王位。他希望这个继承者足够聪明,所以他准备了一个西洋棋盘,上面的每个格子中均有一个 1-99 的数字。他又准备8个皇后棋子。8 皇后的规则就是不能有任何棋子同行或者同列或者同斜线,在满足这个规则的同时,王位继承者还需要让 8 个皇后所在的位置的数字的和是最大的。
输入格式
输入一个数字 k (k≤20),代表棋盘的数量。接下来有 k 个棋盘,每个棋盘有 64 个数字,分成 8 行 8 列出入,具体可见样例,每一个数字均小于 100。
输出格式
每一个棋盘对应输出最大的数值,一共输出 k 行。样例输入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 48 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
样例输出
260
代码解析:
思路一:利用回溯法求解所有八皇后问题的解,把每组解对应的数值之和计算出来然后取最大就是最终的结果。这里写下我自己的回溯法过程,用递归函数来实现。
首先,从第0行开始依次向下在每行放入一个皇后,当前位置可以放入皇后时就去在下一行继续尝试放入皇后,当前位置不可放入皇后即有同列或同斜线的皇后存在时,回退到上一行的皇后位置,让该位置向右移动一位,继续尝试下一行。当所有行都被放入皇后时说明求出一组解,更新答案。
用一个数组x来记录放入皇后的位置,x[i]表示第i行的皇后放在了第x[i]列的位置,未放入时x[i]=-1。求解问题的递归函数是void queen(int k),当k==n时说明8行里全部放入皇后,更新结果,结束递归。否则,在没有冲突即之前已经放入的皇后的位置和当前位置不不同列,不同斜线(判断条件: 斜线的斜率绝对值==1)时在该位置放入皇后并尝试下一行。Bool notDanger(int r,int c) 是判断当前位置是否有冲突的函数。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int n = 8; int tmp, ans; int x[10]; int chess[10][10]; bool notDanger(int r, int c) { for (int i = 0; i < r; i++) { if (x[i] == c) return false; if (abs(r - i) == abs(c - x[i])) return false; } return true; } void queen(int k) {//放入第k行的皇后 if (k == n) { ans = max(ans, tmp); return; }//所有行都尝试完毕,即求出了相应一组解 for (int i = 0; i < n; i++) { if (notDanger(k, i)) {//没有冲突,尝试下一行 x[k] = i; tmp += chess[k][i]; queen(k + 1); x[k] = -1;//注意下层递归结束后及时更新相应变量值 tmp -= chess[k][i]; } } } int main() { int t; scanf("%d", &t); while (t--) { tmp = ans = 0; memset(x, -1, sizeof(x)); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) scanf("%d", &chess[i][j]); } queen(0); printf("%d\n", ans); } return 0; }
方法二:
#include <cstdio> #include <iostream> using namespace std; int n = 0;//棋盘大小 int ans = 0;//解的个数 bool hashTable[20] = {false};//hashtable[i] == true表示第i列被占用 bool xy[20] = {false};//左下-右上 bool yx[20] = {false}; int val[100][100]; int maze[100][100]; int P[20] = {0};//临时存放情况 void dfs(int deep) { if (deep >= n) { for (int i = 0; i < n; i++) { val[ans][i] = P[i]; } ans++; return; } for (int i = 0; i < n; i++) { if (xy[i+deep] == false && yx[i-deep+n] == false && hashTable[i] == false) { xy[i+deep] = true; yx[i-deep+n] = true; hashTable[i] = true; P[deep] = i; dfs(deep+1); hashTable[i] = false; yx[i-deep+n] = false; xy[i+deep] = false; } } } int main() { // cin >> n; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { cin >> maze[i][j]; } } n = 8; dfs(0); int maxn = 0; for (int i = 0; i < ans; i++) { int mmmaxn = 0; for (int j = 0; j < n; j++) { // printf("%d ", val[i][j]); mmmaxn += (maze[j][val[i][j]]); } maxn = max(maxn, mmmaxn); } printf("%d\n", maxn); return 0; }
相关文章推荐
- mongodb-2.6.0 在win7 64下的安装和服务启动
- 在VMware workstations中安装CentOS-7-x86_64-Everything-1611.ISO
- 无法安装64(32)位版本的office,因为在您的pc找到了以下32(64)位程序。此问题的完全解决方案
- 64_j1
- ubuntu 12.10 32(64)位 下安装jdk
- Windows7 Oracle11gR2 64 安装, 以及PL/SQL Developer连接问题
- 64_r3
- GCC 编译错误 relocation truncated to fit: R_X86_64_32S against `.bss'
- aarch64_p6
- install skype on 64 bit linux system
- Base64+动态密码生成
- ios 提交应用中心出现提示:missing 64-bit support
- 编译 Android 系统的 arm64 架构版 busybox
- iOS工程适配64-bit经验分享
- Cannot find a valid baseurl for repo: base/7/x86_64
- 八皇后问题(算法)C++源代码
- relocation truncated to fit: R_X86_64_PC32 against symbolXXX
- iOS开发之32bit转64bit需要注意的地方
- Linux内核版本与系统版本信息查看以及x86与x86_64的区别