对八皇后问题的拓展探究
2013-11-19 09:06
148 查看
对八皇后问题的拓展探究
至繁归于至简,这次自己仍然用尽可能易理解和阅读的解决方式。1、问题说明:
西洋棋中的皇后可以直线前进,吃掉遇到的所有棋子,如果棋盘上有八个皇后,则这八个皇后如何相安无事的放置在棋盘上,1970年与1971年, E.W.Dijkstra与N.Wirth曾经用这个问题来讲解程式设计之技巧。2、解法:
关于棋盘的问题,都可以用递回求解,然而如何减少递回的次数?在八个皇后的问题中,不必要所有的格子都检查过,例如若某列检查过,该该列的其它格子就不用再检查了,这个方法称为分支修剪。下面自己写的的具体代码,以棋盘上的八皇后为例,修改下面的N = 8,即可从八皇后问题拓展至此类所有的棋盘问题。3、具体代码:
/** * @Title 对八皇后问题的拓展探究 * @Author 孙琨 * @Date 2013-11-18 * @At XUST * @All Copyright by 孙琨 * */ #include <iostream> using namespace std; #define N 8 int column[N + 1]; // 同栏是否有皇后,1表示有 int rup[2 * N + 1]; // 右上至左下是否有皇后 int lup[2 * N + 1]; // 左上至右下是否有皇后 int queen[N + 1] = {0}; int num; // 解答编号 void backtrack(int); // 递归求解 int main(void) { int i; num = 0; for(i=1; i<=N; i++) column[i] = 1; for(i=1; i<=2*N; i++) rup[i] = lup[i] = 1; backtrack(1); cout <<endl << N << "个皇后在棋盘上总共有" << num << "种排法" << endl; return 0; } void showAnswer() { int x,y; cout << endl << "解答 " << ++num << endl; for(y=1; y<=N; y++) { for(x=1; x<=N; x++) { if(queen[y] == x) // 放置皇后 cout << "●"; else cout << "○"; } cout << endl; } } void backtrack(int i) { int j; if(i > N) { showAnswer(); } else { for(j=1; j<=N; j++) { if(column[j]==1 && rup[i+j]==1 && lup[i-j+N]==1) { queen[i] = j; // 设定为占用 column[j] = rup[i+j] = lup[i-j+N] = 0; backtrack(i+1); column[j] = rup[i+j] = lup[i-j+N] = 1; } } } }
4、结果部分截图:
相关文章推荐
- 深入探究Swift数组背后的协议、方法、拓展(转)
- 进制问题的几个探究以及拓展
- 深入探究Swift数组背后的协议、方法、拓展
- 发帖水王拓展问题探究
- 八皇后问题(由字符串排列问题拓展)
- 深入探究Swift数组背后的协议、方法、拓展
- 八皇后问题
- 【结论】【数论】拓展欧几里得算法、费马小定理
- flex_探究Flex组件生命周期;
- 阅读郭林《第一行代码》的笔记——第4章 手机平板要兼顾,探究碎片
- 用回溯法解决八皇后问题的C语言程序
- 回溯法——八皇后问题 n-queens
- 函数调用过程探究
- Js类的静态方法与实例方法区分以及jQuery如何拓展两种方法
- C# 中的拓展方法,以StringBuilder加上IndexOf方法举例
- mysql探究之null与not null
- Linq to sql(六):探究特性
- BSGS的一个拓展--模数为合数的做法
- android按键功能的拓展
- 浏览器探究博客