八皇后问题概述

两盒软妹~` 提交于 2020-02-18 22:22:01

八皇后问题是数学史上具有重要地位的问题之一,可以与汉诺塔问题、马走日问题平起平坐。喜欢国际象棋的人一定知道,在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();//搜索并输出 
}

八皇后的第二个典型例题计划明天写。重申一遍,这个代码没有通过!只是我的思路而已!不要妄想白嫖了!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!