国际象棋“皇后”问题的回溯算法

//国际象棋“皇后”问题处理头文件
//国际象棋“皇后”问题的回溯算法
/*
    作者:成晓旭
    时间:2001年10月9日(17:35:38-18:00:00)
    内容:完成“皇后”问题的程序序言部分
    时间:2001年10月9日(14:00:00-15:00:00)
    内容:完成“皇后”问题的程序序言部分
    ===================================================
    问题描述:
        在一个n*n的棋盘上放置n个不能互相捕捉的国际象棋“皇后”,
    并输出所有合理的布局情况.(在国际象棋中,皇后可以沿着纵、横
    及两条斜线共4个方向捕捉对手,可见,合适的解是在每行、每列及
    在一条斜线上只能有一个皇后<皇后相互捕捉>)
    编程思想:
    算法描述:
    {
        输入棋盘大小值n;
        m=0;    //从空配置开始
        notcatch=1;        //空配置中皇后不能相互捕捉
        do
        {
            if(notcatch)
            {
                if(m==n)
                {
                    输出解;
                    调整(形成下一个候选解);
                }
                else
                    扩展当前候选解至下一列;    //向前试探
            }
            else
                调整(形成下一个候选解);        //向后回溯
            notcatch = 检查当前候选解的合理性
        }while(m!=0)
    }
*/
#include "stdlib.h"
#define  MAXN 100
//全局变量及全局工作数组定义
int m,n,NotCatch;
int    ColFlag[MAXN+1];    /*表示第i列的第ColFlag[i]行有皇后,(1:有;0:没有)*/
int RowFlag[MAXN+1];    /*RowFlag[i]:表示第i行没有皇后(1:没有;0:有)*/
int upBiasFlag[2*MAXN+1];    /*upBiasFlag[i]:表示第i条上斜线(右高左斜)没有皇后(1:没有;0:有)*/
int dnBiasFlag[2*MAXN+1];    /*dnBiasFlag[i]:表示第i条下斜线(左高右斜)没有皇后(1:没有;0:有)*/
//显示输入填写的数字
void ArrangeQueen()
{
    int i;
    char answer;
    printf("输入棋盘边格数:");
    scanf("%d",&n);
    for(i=0;i<=n;i++)    /*设置程序初始状态*/
        ColFlag[i] = 1;
    for(i=0;i<=2*n;i++)
        upBiasFlag[i] = dnBiasFlag[i] = 1;
    m = 1;
    ColFlag[1] = 1;
    NotCatch = 1;
    ColFlag[0] = 0;
    do
    {
        if(NotCatch)
        {
            if(m==n)
            {
                printf("列	行");
                for(i=1;i<=n;i++)    /*找到可行解,输出*/
                    printf("%3d	%3d ",i,ColFlag[i]);
                printf("还要继续搜索吗(Q/q for Exit)? ");
                scanf("%c",&answer);
                if(answer=='Q' || answer=='q')
                    exit(0);
                while(ColFlag[m] == n)
                {
                    m--;    /*清除第m-1列,第RowFlag[ColFlag[m-1]]行有皇后的标志*/
                    RowFlag[ColFlag[m]] = upBiasFlag[m+ColFlag[m]] = dnBiasFlag[n+m-ColFlag[m]] = 1;
                }
                ColFlag[m]++;    /*调整第m列的皇后配置(扩展调整)*/
            }
            else
            {
                /*设置第m列,第RowFlag[ColFlag[m-1]]行有皇后的标志*/
                RowFlag[ColFlag[m]] = upBiasFlag[m+ColFlag[m]] = dnBiasFlag[n+m-ColFlag[m]] = 0;
                ColFlag[++m] = 1;    /*向前试探*/
            }
        }
        else
        {    
            while(ColFlag[m]==n)    /*向后回溯*/
            {
                m--;    /*清除第m-1列,第RowFlag[ColFlag[m-1]]行有皇后的标志*/
                RowFlag[ColFlag[m]] = upBiasFlag[m+ColFlag[m]] = dnBiasFlag[n+m-ColFlag[m]] = 1;
            }
            ColFlag[m]++;    /*调整第m列的皇后配置(回溯调整)*/
        }
        NotCatch = RowFlag[ColFlag[m]] && upBiasFlag[m+ColFlag[m]] && dnBiasFlag[n+m-ColFlag[m]];
    }while(m!=0);
}

void dArrange_Queen_All(int k,int n)
{
    int i,j;
    char answer;
    for(i=1;i<=n;i++)
    {
        if(RowFlag[i] && upBiasFlag[k+i] && dnBiasFlag[n+k-i])
        {
            ColFlag[k] = i;
            RowFlag[i] = upBiasFlag[k+i] = dnBiasFlag[n+k-i] = 0;
            if(k==0)
            {
                printf("列	行");
                for(j=1;j<=n;j++)    /*找到可行解,输出*/
                    printf("%3d	%3d ",i,ColFlag[i]);
                printf("还要继续搜索吗(Q/q for Exit)? ");
                scanf("%c",&answer);
                if(answer=='Q' || answer=='q')
                    exit(0);
            }
            else
                dArrange_Queen_All(k+1,n);
            RowFlag[i] = upBiasFlag[k+i] = dnBiasFlag[n+k-i] = 1;
        }
    }
}
void dArrangeQueenAll()
{
    int i;
    printf("输入棋盘边格数:");
    scanf("%d",&n);
    for(i=0;i<=n;i++)    /*设置程序初始状态*/
        ColFlag[i] = 1;
    for(i=0;i<=2*n;i++)
        upBiasFlag[i] = dnBiasFlag[i] = 1;
    dArrange_Queen_All(1,n);
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回溯算法是一种用于解决八皇后问题的有效方法。该问题是在8×8格的国际象棋棋盘上放置8个皇后,使得它们互相之间不能攻击,即不能处于同一行、同一列或同一斜线上。 回溯算法通过递归的方式来搜索所有可能的解。它从第一行开始,依次尝试在每一列放置皇后,并进行递归调用,以确定下一行的皇后位置。如果在某一行放置皇后后,它与之前的皇后产生冲突(在同一列、同一行或同一斜线上),则回溯到上一行,重新选择该行的皇后位置。 这种算法的优势在于它能够通过剪枝操作来避免无效的搜索。当在某一行放置皇后后,发现它与之前的皇后产生冲突时,可以提前结束该分支的搜索,从而减少了不必要的尝试。 使用回溯算法解决八皇后问题可以得到所有合法的解。根据引用的描述,经过旋转和对称变换,共有42类不同的解。而根据引用的描述,使用回溯算法可以找到92种不同的解。 总结起来,回溯算法是一种高效解决八皇后问题的方法,它通过递归和剪枝操作来搜索所有合法的解。使用该算法可以找到92种不同的解。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [八皇后问题回溯法)](https://blog.csdn.net/skill_Carney/article/details/107446299)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值