八皇后问题之一(枚举+搜索)

问题描述
    会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如
何将8 个皇后放在棋盘上(有8 * 8 个方格),使它们谁也不能被吃掉!这就是著名的八皇后
问题。 对于某个满足要求的8 皇后的摆放方法,定义一个皇后串a 与之对应,即a=b1b2...b8,
其中bi 为相应摆法中第i 行皇后所处的列数。已经知道8 皇后问题一共有92 组解(即92 个
不同的皇后串)。给出一个数b,要求输出第b 个串。串的比较是这样的:皇后串x 置于皇
后串y 之前,当且仅当将x 视为整数时比y 小。
输入数据
第 1 行是测试数据的组数n,后面跟着n 行输入。每组测试数据占1 行,包括一个正整
数b(1 <= b <= 92)
输出要求
n 行,每行输出对应一个输入。输出应是一个正整数,是对应于b 的皇后串
输入样例
2
1
92
输出样例
15863724

84136275

解题思路:

   我们有一个8*8 的矩阵仿真棋盘标识当前已经摆放好的棋子所控制的区域。
用一个有92 行每行8 个元素的二维数组记录可行的摆放方法。用一个递归程序来实现
尝试摆放的过程。基本思想是假设我们将第一个棋子摆好,并设置了它所控制的区域,
则这个问题变成了一个7 皇后问题,用与8 皇后同样的方法可以获得问题的解。那我们
就把重心放在如何摆放一个皇后棋子上,摆放的基本步骤是:从第1 到第8 个位置,顺
序地尝试将棋子放置在每一个未被控制的位置上,设置该棋子所控制的格子,将问题变
为更小规模的问题向下递归,需要注意的是每次尝试一个新的未被控制的位置前,要将
上一次尝试的位置所控制的格子复原。



#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int QueenPalce[92][8]; //存放92种皇后棋子的摆放方法
int count = 0;
int bord[8][8];        //模拟棋盘
void putQueen(int ithQueen); //递归函数,每次摆好一颗棋子

int main()
{
    freopen("in.txt","r",stdin);
    int n,i,j;
    for(i=0; i<8; i++)
    {
        for(j=0; j<8; j++) //棋盘初始化
            bord[i][j] = -1;

        for(int i=0; i<92; i++) //存放数组初始化
            QueenPalce[j][i] = 0;
    }
    putQueen(0);  //从第零个棋子开始摆放,函数最终目的是生成QueenPlace数组
    scanf("%d",&n);  //测试数据格数

    for(int i =0; i<n; i++)
    {
        int ith;  //第i个棋子
        scanf("%d",&ith);
        for(int j=0; j<8; j++)
            printf("%d",QueenPalce[ith-1][j]);//输出第i个棋子的皇后串
        printf("\n");
    }
    return 0;
}

void putQueen(int ithQueen)  //摆放函数
{
    int i,k,r;
    if(ithQueen == 8)  //如果是第8颗棋子
    {
        count++;       
        return;
    }
    for(i=0; i<8; i++)
    {
        if(bord[i][ithQueen]==-1) //从第1位置到第8位置顺序尝试
        {
            bord[i][ithQueen] = ithQueen; //摆放皇后
            for(k=count; k<92; k++)
                QueenPalce[k][ithQueen] = i+1;//其后的第ith个皇后放在第i+1位上

            for(k=0; k<8; k++)   //设置该摆放皇后棋子的控制范围
                for(r=0; r<8; r++)
                    if(bord[k][r]==-1&&(k==i||r==ithQueen||abs(k-i)==abs(r-ithQueen)))
                        bord[k][r]=ithQueen;

            putQueen(ithQueen+1);  //向其后的棋子递归

            for(k=0; k<8; k++)  //解除上级棋子的控制范围
                for(r=0; r<8; r++)
                    if(bord[k][r]==ithQueen)
                        bord[k][r]=-1;
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值