八皇后问题(回溯递归-C语言-简单求解)

题目详解

八皇后问题,是由国际象棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。

问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

回溯算法

回溯思想:有冲突解决冲突,没有冲突往前走,无路可走往回退,走到最后是答案。

代码 

#include <stdio.h>
int Queenes[8]={0},Counts=0;
int Check(int line,int list)
{
    //遍历该行之前的所有行
    for (int index=0; index<line; index++) 
	{
        //挨个取出前面行中皇后所在位置的列坐标
        int data=Queenes[index];
        //如果在同一列,该位置不能放
        if (list==data) {
            return 0;
        }
        //如果当前位置的斜上方有皇后,在一条斜线上,也不行
        if ((index+data)==(line+list)) {
            return 0;
        }
        //如果当前位置的斜下方有皇后,在一条斜线上,也不行
        if ((index-data)==(line-list)) {
            return 0;
        }
    }
    //如果以上情况都不是,当前位置就可以放皇后
    return 1;
}
//输出语句
void print()
{
    for (int line = 0; line < 8; line++)
    {
        int list;
        for (list = 0; list < Queenes[line]; list++)
            printf("0");
        printf("#");
        for (list = Queenes[line] + 1; list < 8; list++)
		{
            printf("0");
        }
        printf("\n");
    }
    printf("================\n");
}

void eight_queen(int line){
    //在数组中为0-7列
    for (int list=0; list<8; list++) 
	{
        //对于固定的行列,检查是否和之前的皇后位置冲突
        if (Check(line, list))
		 {
            //不冲突,以行为下标的数组位置记录列数
            Queenes[line]=list;
            //如果最后一样也不冲突,证明为一个正确的摆法
            if (line==7) 
			{
                //统计摆法的Counts加1
                Counts++;
                //输出这个摆法
                print();
                //每次成功,都要将数组重归为0
                Queenes[line]=0;
                return;
            }
            //继续判断下一样皇后的摆法,递归
            eight_queen(line+1);
            //不管成功失败,该位置都要重新归0,以便重复使用。
            Queenes[line]=0;
        }
    }
}
int main()
{
    //调用回溯函数,参数0表示从棋盘的第一行开始判断
    eight_queen(0);
    printf("摆放的方式有%d种",Counts);
    return 0;
}

(by 归忆)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

归忆_AC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值