C++解决八皇后问题
2012-12-01 13:44
274 查看
近日,因老师布置的一道题目才知道有八皇后这个问题,首先介绍一下八皇后问题吧。
八皇后问题:
设法在国际象棋的棋盘上放置八个皇后,使得其中任何一个皇后所处的“行”、“列”以及“对角线”上都不能有其它的皇后。
国际象棋棋盘其实就是一个8*8的方格子组成的,我们可以看成是8*8的数组。
我最初的想法是利用结构体,构造皇后这么一个结构,它有 row(行) 和 line(列) 俩个数据.然后在 main 主方法中先创建一个全为0的8*8数组(即棋盘)。
接着,分析题目可知,每一列必定有一个皇后,即这八个皇后必定分布在第一列....到第八列。然后利用循环遍历每一列,若发现某一个位置为0,则将皇后放入,并按照题目要求,对该位置所处的行和列级对角线均赋值1;直到找到第八个皇后。然而看似简单,其实仔细一想,要是找到第7个了,但是第8个没位置了怎么办?!
嗯,我想了一会儿,那撤销对第7个皇后的操作(之前赋值了1,现在必须重新赋值0),然后另找第7个的位置(因为第7个皇后的位置不唯一(可能哈)),但是可能会出现,所有第7个皇后的位置找遍了,8的位置还是不能确定,那么又得重新确定第6个皇后的位置.......总而言之就是当遇到某个皇后找不到合适位置时,必须回溯到前一个皇后,改变它的位置,如果还是无法确定,必须回溯到前前一个皇后.......想着想着逻辑就乱了。
嗯,烦的慌,玩会儿神庙逃亡再说........(半个小时后)....
貌似可以这样.....
每个皇后的位置只有八种可能(行确定,列待定),如第一个皇后只可能出现在:第一行第一列,第一行第二列......第一行第八列。所以8个皇后就有 8的8次方 种可能。只要她们俩俩之间满足一定的关系,就可以得出解决方案~~!!然后怒码代码!
这种方法比较暴力,它验证了所有的可能(一些不需要验证的可能它也验证了,造成了效率的降低)并对每种可能进行了 28 次比较,所以运行时间会有些漫长,甚至在命令行里放不下所有的结果(最后有92种结果,如果把换行符endl去掉的话,就可以解决)。不过它能保证得出全面的正确的结果。不会漏解。
更高效的方法还有很多,大家可以google。我只是把我知道的分享给大家而已,毕竟出来混,总是要还的。
八皇后问题:
设法在国际象棋的棋盘上放置八个皇后,使得其中任何一个皇后所处的“行”、“列”以及“对角线”上都不能有其它的皇后。
国际象棋棋盘其实就是一个8*8的方格子组成的,我们可以看成是8*8的数组。
我最初的想法是利用结构体,构造皇后这么一个结构,它有 row(行) 和 line(列) 俩个数据.然后在 main 主方法中先创建一个全为0的8*8数组(即棋盘)。
接着,分析题目可知,每一列必定有一个皇后,即这八个皇后必定分布在第一列....到第八列。然后利用循环遍历每一列,若发现某一个位置为0,则将皇后放入,并按照题目要求,对该位置所处的行和列级对角线均赋值1;直到找到第八个皇后。然而看似简单,其实仔细一想,要是找到第7个了,但是第8个没位置了怎么办?!
嗯,我想了一会儿,那撤销对第7个皇后的操作(之前赋值了1,现在必须重新赋值0),然后另找第7个的位置(因为第7个皇后的位置不唯一(可能哈)),但是可能会出现,所有第7个皇后的位置找遍了,8的位置还是不能确定,那么又得重新确定第6个皇后的位置.......总而言之就是当遇到某个皇后找不到合适位置时,必须回溯到前一个皇后,改变它的位置,如果还是无法确定,必须回溯到前前一个皇后.......想着想着逻辑就乱了。
嗯,烦的慌,玩会儿神庙逃亡再说........(半个小时后)....
貌似可以这样.....
每个皇后的位置只有八种可能(行确定,列待定),如第一个皇后只可能出现在:第一行第一列,第一行第二列......第一行第八列。所以8个皇后就有 8的8次方 种可能。只要她们俩俩之间满足一定的关系,就可以得出解决方案~~!!然后怒码代码!
#include "stdafx.h" #include <iostream> using namespace std; //判断是否得出结果 bool judgeGetResult(int* a,const int large); int main(int argc, char* argv[]) { int count = 0; //计数结果个数 int num_Row[8]; //皇后的列位置 for(int row_1 = 0;row_1 < 8;row_1++) //在第一行,从第一列遍历到第八列 { num_Row[0] = row_1; //记下第一行皇后的列位置 for(int row_2 = 0;row_2 < 8;row_2++) //在第二行,从第一列遍历到第八列,以下递推 { num_Row[1] = row_2; //记下第二行皇后的列位置,以下递推 for(int row_3 = 0;row_3 < 8;row_3++) { num_Row[2] = row_3; for(int row_4 = 0;row_4 < 8;row_4++) { num_Row[3] = row_4; for(int row_5 = 0;row_5 < 8;row_5++) { num_Row[4] = row_5; for(int row_6 = 0;row_6 < 8;row_6++) { num_Row[5] = row_6; for(int row_7 = 0;row_7 < 8;row_7++) { num_Row[6] = row_7; for(int row_8 = 0;row_8 < 8;row_8++) { num_Row[7] = row_8; if(judgeGetResult(num_Row,8)) //得出结果,并输出到屏幕上 { cout<<"得出结果:"<<endl; for(int i = 0;i< 8;i++) cout<<"皇后"<<i+1<<" "<<"("<<i+1<<","<<num_Row[i]<<")"<<endl; count++; } } } } } } } } } cout<<"最后有 "<<count<<" 个解决方案"; return 0; } bool judgeGetResult(int* a,const int large) { for(int i = 0; i < large;i++) for(int j = i+1;j < large;j++) if(a[i] == a[j] || (a[i] - a[j]) == (i - j) || (a[i] - a[j]) == (j - i))//判断 俩俩 皇后之间是否满足八皇后问题的要求(就是我说的满足一定的关系) return false; //不满足 return true; //满足 }
这种方法比较暴力,它验证了所有的可能(一些不需要验证的可能它也验证了,造成了效率的降低)并对每种可能进行了 28 次比较,所以运行时间会有些漫长,甚至在命令行里放不下所有的结果(最后有92种结果,如果把换行符endl去掉的话,就可以解决)。不过它能保证得出全面的正确的结果。不会漏解。
更高效的方法还有很多,大家可以google。我只是把我知道的分享给大家而已,毕竟出来混,总是要还的。
相关文章推荐
- c++ 深度优先算法解决八皇后问题
- C++解决八皇后问题
- 八皇后问题之C++解决
- C++解决八皇后问题
- C++基于回溯法解决八皇后问题示例
- 解决linux eclipse c++找不到符号或者~~~name a type的问题 && c++11
- C++智能指针(三):weak_ptr--解决shared_ptr循环引用问题
- 用C++解决:把数组排成最小的数问题
- 关于Cocos C++ http 有中文参数 服务器接收乱码问题解决!
- 动态规划法解决TSP问题(C++)
- stm32建c++与c混合工程遇到的问题及解决
- 使用SSD目标检测c++接口编译问题解决记录
- !!!您也使用托管C++吗?--此文能解决大部分问题
- 在Eclipse下编译C++程序出现的Launch failed.Binary not found.问题的解决方法
- <c++>利用deque容器,解决约瑟夫环问题
- 解决C/C++中的 multiple definition of 问题
- 我的第二十四个C++上机报告(穷举法解决组合问题之百钱百鸡问题)
- c/c++中涉及中文编码问题的解决方法
- OpenWRT开发之——对C++的支持(解决库依赖问题)
- 回溯法加剪枝解决01背包问题(C++)