蓝桥杯day2-DFS:acwing-843. n-皇后问题

(图:AcWing 843. n-皇后问题(按行枚举或按每个元素枚举) - AcWing

#include <iostream>
using namespace std;
const int N = 20; //为什么不是10 因为对角线的条数为2n-1 

// bool数组用来判断搜索的下一个位置是否可行
// col列,dg对角线,udg反对角线
// g[N][N]用来存路径

int n;
char g[N][N];//因为数组里的元素是"." 和 Q 两者都被定义为字符型 故存放的的数组定义为char
bool col[N], dg[N], udg[N];

void dfs(int u) {     //按行枚举,且经过分析,每行只能有一个皇后
    // u == n 表示已经搜了n行,故输出这条路径
    if (u == n) {
        for (int i = 0; i < n; i ++ )  cout << g[i] << endl;   //g[i]代表二维数组的第i行 表示换行
        puts("");  // 换行 空出一行
        return;
    }

    // 枚举u这一行,搜索合法的列
    int x = u;
    for (int y = 0; y < n; y ++ )
        // 剪枝(对于不满足要求的点,不再继续往下搜索)  
        if (col[y] == false && dg[y - x + n] == false && udg[y + x] == false) {
            col[y] = dg[y - x + n] = udg[y + x] = true;
            g[x][y] = 'Q';//不可用" "
            dfs(x + 1);   //迭代上下完全对称
            g[x][y] = '.'; //不可用" "
            col[y] = dg[y - x + n] = udg[y + x] = false; // 恢复现场
        }
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            g[i][j] = '.';//不可用" "

    dfs(0);

    return 0;
}   

 复盘独立敲一遍的错误汇总:

#include <iostream>
using namespace std;

const int N = 20;//因为斜对角线的个数为2n-1 
int n;
char g[N][N];//将棋盘定义为一个二维数组
bool col[N],dg[N],udg[N];//用来标记是否能用

void dfs(int u)
{
    if(u==n)//如果最后一行也填完,则输出
    {
        for(int i=0;i<n;i++)
        {
            cout<<g[i]<<endl;//n*n的二维数组可视为n行含n个元素的一维数组,此处为输出第i行
        }
        cout<<endl;//每个结果之间有空行
    }
    
    int x=u;
    for(int y=0;y<n;y++)
    {
        if(!col[y]&& !dg[y-x+n] &&!udg[x+y])//注意:正对角线为竖轴-横轴
        //1.若对于第x行,第y列此空位,同列+正对角线+副对角线都未被利用,则可填入
        //2.为什么不考虑同行呢,因为根据要求,直接安排每一行只能填一个,以此来简化操作
        {
            g[x][y]='Q';
            col[y]=dg[y-x+n]=udg[x+y]=true;//col[y] col表示列
            dfs(u+1);//递归填好,到下一行
            //递归上下操作完全对称,但具体操作内容相反
            col[y]=dg[y-x+n]=udg[x+y]=false;//恢复现场:1.状态 2.
            g[x][y]='.';
        }
    }
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)//预先将所有位置填.表示空
    {
        for(int j=0;j<n;j++)
        {
            g[i][j]='.';
        }
    }
    dfs(0);
    return 0;
}

/*
此次复盘错误点
1.主函数未把棋盘空位置'.'(不是cin>>'.')
2. 对于char 变量 用'' 而非""
3.正对角线为 竖轴-横轴+n
4.对角线的条数为2n-1 故设置const 常量作为数组空间时,一定记得是否够用不溢出
5.col为列 
6.main 不要写成mian啊啊啊啊
*/

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值