八皇后问题(dfs解法)-计蒜客

 

关于八皇后问题,在计蒜客上题目是这样的。

 

    努比亚和苏丹没有子女,所以他要从一些有集成资格的继承者中挑选一个出来继承王位。他希望这个继承者足够聪明,所以他准备了一个西洋棋盘,上面的每个格子中均有一个 1-99 的数字。他又准备了 8 个皇后棋子。

  8 皇后的规则就是不能有任何棋子同行或者同列或者同斜线,在满足这个规则的同时,王位继承者还需要让 8 个皇后所在的位置的数字的和是最大的。皇后其实就好像中国象棋中的车,只不过算上了对角线。

输入格式

输入一个数字 k(k≤20)代表棋盘的数量。

接下来有 k 个棋盘,每个棋盘有 64个数字,分成 8 行 8 列出入,具体可见样例,每一个数字均小于 100。

输出格式

每一个棋盘对应输出最大的数值, 一共输出 k 行。

 

样例

1
1  2  3  4  5  6  7  8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
48 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64

 

输出

260

 

解析:

     对于八皇后问题此题在八皇后问题的基础上增加了数值,要求求出每组正确解法所对应棋盘上的数之和最大的一组并输出最大值,所以此题在八皇后问题上做一点改动即可,在dfs解法中如果满足放皇后的条件那么就在此处做标记表示放下了皇后,在此使用两个二维数组,一个map1用来存棋盘,‘0’表示没有放皇后,而map2用来存棋盘上相应的数值,在做标记的时候只要让计数器sum加上map2中相应位置存的数字,在取消标记的时候再减去map2中相应位置的数字,在判断递归终点的时候比较ans和sum的大小,ans保留大的值就可以了。

 

 

 

代码如下:

#include
#include
using namespace std;
int  map2[10][10],map1[10][10],C[100];
int i,j,ans,sum;
bool cheak(int x,int y)                               //判断此处能否放皇后的函数cheak
{
    for(int i=x-1; i>=0; i--)           //判断在这一列可以放
    {
        if(map1[i][y])return false;
    }
    for(int i=y-1; i>=0; i--)         //判断在这一行可以放
    {
        if(map1[x][i])return false;
    }


    int min=(x>y)?y:x;               
    int min2=(7-y>x)?x:7-y;


    for(int i=min; i>=1; i--)         //判断这一点左对角线可以放
    {
        if(map1[x-i][y-i])return false;
    }
    for(int i=min2; i>=1; i--)           //判断这一点右对角线可以放
    {
        if(map1[x-i][y+i])return false;
    }
    return true;
}
void dfs(int q,int num)                       //深搜过程
{
    if(q == 64||num == 0)
    {
        if(num == 0&&sum > ans)
        {
            ans=sum;
        }
        return;
    }
    int x=q/8;                              //求出该点坐标
    int y=q%8;
    if(map1[x][y]==0 && cheak(x,y))
    {
        map1[x][y]++;                             //在map1上标记此处放皇后
        sum + = map2[x][y];                   //在标记同时,sum加上map2存的数值
        dfs(q + 1,num - 1);
        map1[x][y]--;                             //在map1上取消标记
        sum - = map2[x][y];                  //在取消标记同时,sum减去map2存的数值
    }
    dfs(q+1,num);
}
int main()             //建议从主函数开始读程序
{
    int t;
    cin>>t;
    while(t--)
    {
        sum=0;
        ans=0;
        memset(map1,0,sizeof(map1));     //清空map1数组
        for(i=0; i<=7; i++)
        {
            for(j=0; j<=7; j++)
            {
                cin>>map2[i][j];
            }
        }
        dfs(0,8);
        cout<     }
}

小生不才,多有指正,蟹蟹。。。

你可能感兴趣的:(八皇后问题(dfs解法)-计蒜客)