解题思路:相比看过之前的楼主写过的代码太过与繁杂,在这边的思路就是发现每一条斜线的行-行等于列-列。例如(1,1),(2,2),会发现2-1=2-1.
所以这里只需要用一维数组判断是否为同一列或者同一斜线即可(可参考bool black(white))。这里先放白皇后,利用回溯法,白皇后放过的格子定义为0表示不能再放了,先列出白皇后放的一种,然后再跳转到黑皇后放置,黑皇后放置成功到n+1行的话ans++ 表示这为第一种,然后重复以上方法即可

注意事项:用到的bool类型属于c++里面的,所以编译的时候要改为c++不然会报错



#include
#include
#include
int map[20][20]; 
int n;
int white1[20];//表示白皇后放过的方格
int black1[20];//表示黑皇后放过的方格
bool white(int i,int j);//判断白皇后是否可以放置
bool black(int i,int j);//同理
void dfs1(int i);
int ans=0;
void dfs(int i)
{
    if(i==(n+1))
    {
        dfs1(1);
        return;
    }
    for(int j=1;j<=n;j++)
    if(map[i][j]!=0&&white(i,j))
    {
        white1[i]=j;
        map[i][j]=0;//这边注意的是每次都会回溯直到白皇后被成功放置,然后跳转到黑皇后放置完,白皇后再回溯
        dfs(i+1);
        map[i][j]=1;
    }
}
void dfs1(int i)
{
    if(i==(n+1))
    {
        ans++;
        return;
    }
    for(int j=1;j<=n;j++)
    if(map[i][j]!=0&&black(i,j))
    {
        black1[i]=j;
        dfs1(i+1);
    }
}
bool white(int i,int j)
{ if(i==1)
    return true;
    for(int k=1;k<i;k++)
    if(white1[k]==j||abs(i-k)==abs(j-white1[k]))
    {
        return false;
    }
        return true;
}
bool black(int i,int j)
{
    if(i==1)
        return true;
    for(int k=1;k<i;k++)
    if(black1[k]==j||abs(i-k)==abs(j-black1[k]))
    {
        return false;
    }
        return true;
}
int main()
{

scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
   scanf("%d",&map[i][j]);
    dfs(1);
printf("%d",ans);

return 0;

}




点赞(0)
 

0.0分

1 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论