近日,因老师布置的一道题目才知道有八皇后这个问题,首先介绍一下八皇后问题吧。
八皇后问题:
设法在国际象棋的棋盘上放置八个皇后,使得其中任何一个皇后所处的“行”、“列”以及“对角线”上都不能有其它的皇后。
国际象棋棋盘其实就是一个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。我只是把我知道的分享给大家而已,毕竟出来混,总是要还的。