2020-10-2 //严蔚敏《数据结构》 //回溯法y与树的遍历:n皇后问题

我回来了,发现之前写的代码有错误,进行了改正:
链接:正确的n皇后问题求解

//严蔚敏《数据结构》
//回溯法y与树的遍历:n皇后问题
//同一对角线包含主对角线、副对角线,还有其他的对角线
//调试器挺好用的
//自学中,加油!!!
#include<iostream>
using namespace std;

void Output_Chessboard(int** chessboard,int n)//输出棋盘(从1行1列开始(因为分配空间n+1,下标0~n))
{
    cout<<"----"<<endl;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            cout<<chessboard[i][j]<<' ';
        cout<<endl;
    }
    cout<<"----"<<endl;
}

bool Insert_Chesspiece(int** chessboard,int n,int i,int j)//放置1个棋子于棋盘的第i行第j列
{
    chessboard[i][j]=1;
    return true;
}

bool Delete_Chesspiece(int** chessboard,int n,int i,int j)//删除于棋盘的第i行第j列的棋子
{
    chessboard[i][j]=0;
    return true;
}

bool IsLegal(int** chessboard,int n,int i,int j)
//前i-1行的棋子已经互不攻击,现判断位于第i行第j列的棋子是否合法(用该棋子与前i-1行的棋子比较即可)
{
    for(int k=1;k!=i;k++){//遍历前i-1行并找到前i-1行的棋子的位置
        //bug1:之前循环结束的条件:k<=i,这个会一直返回false,这个错误,应该为k!=i(k的范围1~i-1)
        for(int l=1;l<=n;l++){
            if(chessboard[k][l]==1){
                if(l==j||(j-l)/(i-k)==1||(j-l)/(i-k)==-1)//若同一列或同一对角线
                    return false;
            }
        }
    }
    return true;
}

void Trial(int** chessboard,int n,int i)
//棋盘chessboard前i-1行已经互不攻击,现对棋盘第i行进行处理
{
    if(i>n)
        Output_Chessboard(chessboard,n);
    else{
        for(int j=1;j<=n;j++){
            Insert_Chesspiece(chessboard,n,i,j);
            if(IsLegal(chessboard,n,i,j))
                Trial(chessboard,n,i+1);
            Delete_Chesspiece(chessboard,n,i,j);
        }
    }
}

int main()
{
    int n;
    cout<<"输入棋盘的行列数";
    cin>>n;
    int** chessboard=new int*[n+1];//多开辟一行空间,棋盘0行未用
    for(int i=0;i!=n+1;i++)
        chessboard[i]=new int[n+1];//多开辟一列空间,棋盘0列未用
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            chessboard[i][j]=0;
    }
    //chessboard的第0行、第0列未用,我选择从chessboard[1][1]开始放置
    //棋盘的行:1~n、列:1~n
    Trial(chessboard,n,1);
    return 0;
}

输入棋盘的行列数:4
----
0 1 0 0
0 0 0 1
1 0 0 0
0 0 1 0
----
----
0 0 1 0
1 0 0 0
0 0 0 1
0 1 0 0
----

Process returned 0 (0x0)   execution time : 0.802 s
Press any key to continue.

输入棋盘的行列数:5
----
1 0 0 0 0
0 0 1 0 0
0 0 0 0 1
0 1 0 0 0
0 0 0 1 0
----
----
0 1 0 0 0
0 0 0 1 0
1 0 0 0 0
0 0 1 0 0
0 0 0 0 1
----
----
0 1 0 0 0
0 0 0 0 1
0 0 1 0 0
1 0 0 0 0
0 0 0 1 0
----
----
0 0 0 1 0
1 0 0 0 0
0 0 1 0 0
0 0 0 0 1
0 1 0 0 0
----
----
0 0 0 1 0
0 1 0 0 0
0 0 0 0 1
0 0 1 0 0
1 0 0 0 0
----
----
0 0 0 0 1
0 0 1 0 0
1 0 0 0 0
0 0 0 1 0
0 1 0 0 0
----

Process returned 0 (0x0)   execution time : 0.822 s
Press any key to continue.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值