八皇后问题是数学史上具有重要地位的问题之一,可以与汉诺塔问题、马走日问题平起平坐。喜欢国际象棋的人一定知道,在8*8的棋盘里,皇后所在的行、列和斜线上不能放棋子,也就是说行、列和斜线是皇后的攻击范围。八皇后问题的主要内容是,在8*8的棋盘上摆放8个皇后,让他们不能相互吃掉。也就是说,每行、每列、每条斜线上至多有一个皇后棋子。实际上,每行、每列上都会有一个皇后棋子。
1.生成所有符合条件的情况。“1”代表皇后,“0”代表空位。(一本通题库1213)
在这里我只提供一个思路。设计出来的程序不知为何无法通过(所以不要妄想白嫖了),但是它的确形成了所有的可能情况。
看了大佬们的讲解,里面有各种取余、加减等运算,竟然都是在数组下表里完成,比如"a[y-x%10+1]=b[x+y-1]“这样很复杂的表达式。毕竟我的智商不够,只能像狗走直线拣骨头一样,用最简单的思路。
请读者们想想,人类解决这样的问题,最直接的方法是什么?
如果你的脑回路和常人差不多的话,回答大概是:“列出所有的可能情况,再一个个排除!”或者是“一行(或一列)摆一个,判断符不符合条件!”
于是,大体的思路出来了。用搜索枚举所有情况,遇到不可行的情况就跳过!
首先,先写出检验一个点(x,y)是否能放棋子的函数:
bool a[100][100];//棋盘 int now=1;//当前方案 bool isOK(int x,int y)//检验一个点能否放皇后 { for(int i=0;i<8;i++)//从列寻找 { if(i==x) continue;//自己的就算了,跳过(下同) if(a[i][y]==true) return false; } for(int j=0;j<8;j++)//从排寻找 { if(j==y) continue; if(a[x][j]==true) return false; } int p=x,q=y; while(true)//向右下 { if(p>=8||q>=8||p<0||q<0) break;//不能越界 p++; q++; if(a[p][q]==true) return false; } p=x;q=y; while(true)//向左下 { if(p>=8||q>=8||p<0||q<0) break; p--; q++; if(a[p][q]==true) return false; } p=x;q=y; while(true)//向右上 { if(p>=8||q>=8||p<0||q<0) break; p++; q--; if(a[p][q]==true) return false; } p=x;q=y; while(true)//向左上 { if(p>=8||q>=8||p<0||q<0) break; p--; q--; if(a[p][q]==true) return false; } return true; }
a[x][y]储存了这个点是否已放置棋子(值为1代表已放,0代表未放)。
然后就是搜索:
void dfs(int start=0)//搜索主函数 { if(start==8)//8列已经全部搜完 { print();//输出这种情况 return; } for(int i=start;i<8;i++)//从第一列开始到最后一列 { for(int j=0;j<8;j++)//遍历一排 { if(isOK(i,j)==false) continue; //这个点不符合要求 else //选到一个皇后 { a[i][j]=true; dfs(start+1);//从下一列到最后一列递归 a[i][j]=false; //回溯 } } return; } }
最后是main:
int main() { memset(a,0,sizeof(a));//初始化 dfs();//搜索并输出 }
八皇后的第二个典型例题计划明天写。重申一遍,这个代码没有通过!只是我的思路而已!不要妄想白嫖了!
来源:https://www.cnblogs.com/jiangyuechen/p/12328940.html