原题链接:蓝桥杯基础练习VIP-2n皇后问题
解题思路:相比看过之前的楼主写过的代码太过与繁杂,在这边的思路就是发现每一条斜线的行-行等于列-列。例如(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分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复