回朔算法

这里写图片描述

1)问题描述

  • 按行来放皇后,从0~7
  • 每一行可放0~7中的一列,一个位置
  • 但是皇后,不能在同一对角线上(左,右),不能再同一列,同一行。

2)算法描述

  • 用col来存储对应列,已存的 j 列col[j]=1
  • 用left来存储左斜线,已占的斜线left[i+j]=1
  • 用right来存储右斜线,已占的斜线right[7+i-j]=1
  • Q来遍历每一行时, i 行用Q[i](栈)来存储 j 列

3)代码描述
①用栈来描述

#include<stdio.h>

int Q[8];//放行和列
int col[8]={0};//将其初始化为零,表示列没有被占
int left[15]={0};//将其初始化为零,表示左斜线没有被占
int right[15]={0};//将其初始化为零,表示右斜线没有被占

int cnt=0;//计数
//输出Queen
void PrintQueen()
{
    printf("\n\n");
    printf("%2d:\n",++cnt);
    int i,j;
    for(i=0;i<8;i++)
    {
        for(j=0;j<8;j++)
        {
            if(Q[i]==j)
                printf("%2d",Q[i]);
            else
                printf("%2c",'x');

        }
        printf("\n");
    }

}

//放皇后
void Queen()
{

    int i=0,j=0;//i为行,j为列
    while(i<8)
    {
        for(;j<8;j++)//遍列可填的列
        {
            if(!col[j] && !left[i+j] && !right[7+i-j])//满足的条件的列
            {
                Q[i]=j;//放皇后
                col[j]=left[i+j]=right[7+i-j]=1;//相应的一占
                i++;
                j=0;

                if(i==8)//找到一个符合输出
                {
                    PrintQueen();
                    j=8;
                }
                break;
            }
        }
        if(j==8)//回朔
        {
            j=Q[--i];
            col[j]=left[i+j]=right[7+i-j]=0;
            j++;
        }
    }

}

int main(void)
{
    Queen();
    return 0;
}

②用递归来描述

#include<stdio.h>

int Q[8];
int col[8]={0};//将其初始化为零,表示列没有被占
int left[15]={0};//将其初始化为零,表示左斜线没有被占
int right[15]={0};//将其初始化为零,表示右斜线没有被占

int cnt=0;//计数
//输出Queen
void PrintQueen()
{
    printf("\n\n");
    printf("%2d:\n",++cnt);
    int i,j;
    for(i=0;i<8;i++)
    {
        for(j=0;j<8;j++)
        {
            if(Q[i]==j)
                printf("%2d",Q[i]);
            else
                printf("%2c",'x');

        }
        printf("\n");
    }

}

//放皇后
void Queen(int i)
{
    int j;
    for(j=0;j<8;j++)
    {
        if(!col[j] && !left[i+j] && !right[7+i-j])
        {
            Q[i]=j;
            col[j]=left[i+j]=right[7+i-j]=1;
            if(i<7)
                Queen(i+1);//继续往后放
            else
                PrintQueen();//放满就输出
            col[j]=left[i+j]=right[7+i-j]=0;//回朔回来
        }
    }
}
int main(void)
{
    Queen(0);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值