AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

1219八皇后

作者: 作者的头像   cccccccup ,  2025-05-10 13:54:54 · 福建 ,  所有人可见 ,  阅读 2


0


题目

微信截图_20250510134840.png

分析

和模版题的不同

输出时,要求输出按照字典序排列的前三个解,以及解的总数

看到字典序

我想到,用string s[N]存下所有的解,然后对s进行sort排序,就可以把所有的解进行字典序排序了

没错

但是不排序也没事,因为遍历填写列的时候,就是从小到大遍历的,因此答案的结果也就自然会按照字典序排列

易错点

没必要的存储

可以只存下前三个解,当idx>3时,可以不用存了

没必要的操作

sort排序
因此也可以用int ans[3][N];

关于对照中的易错点

如果映射成字符的阿拉伯数字,超过9之后就会出现错误(这一点在很多场合中都容易忘记出错)
所以我映射成了A B C....
然后建立一个从字母到数字的表用于输出

关于下标的问题

up中的下标不能直接写[i-u],因为会出现负数,为了防止出现负数,+n进行平移,[i-u+n]
这种思路在很多中常见(有点像取模防止负数的思路)

#include <bits/stdc++.h>
using namespace std;

const int N=15;
const int M=N*2;
const int SIZE=1e6+7;
int n;
int res[N];//当前结果
int col[N],up[M],down[M];
string ans[SIZE];
int idx;

//下标0要空出来,因为答案存的是从1开始填写的
int contrast[14]={0,1,2,3,4,5,6,7,8,9,10,11,12,13};

void dfs(int u)
{
    //当前要填写的是第u行
    if(u==n+1){
        //表示第1行到第n行都填好了,把答案存到ans字符串数组中
        for(int i=1;i<=n;i++){
            ans[idx]+=res[i]+'A';
            //易错点:如果存成数字,10、11...就无法用一个字符村
            //把数字存成字母,因为n最大是13<26,所以足够的
            //注意,因为要用字典序,所以要保证映射前后,字符间的相对字典序是不变的
        }
        idx++;
        return ;
    }

    //填写第u行
    for(int i=1;i<=n;i++){
        if(!col[i]&&!up[i-u+n]&&!down[i+u]){
            res[u]=i;
            col[i]=up[i-u+n]=down[i+u]=true;
            dfs(u+1);
            col[i]=up[i-u+n]=down[i+u]=false;
        }
    }
}
int main()
{
    scanf("%d",&n);
    dfs(1);
    sort(ans,ans+idx);//没有排序也是按照字典序输出,因为我们遍历列的时候是从小到大遍历的
    for(int i=0;i<3;i++){
        for(int j=0;j<ans[i].size();j++) printf("%d ",contrast[ans[i][j]-'A']);
        printf("\n");
    }
    printf("%d\n",idx);
    return 0;
}

0 评论

App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息