您的位置:首页 > 其它

基础练习 2n皇后问题

2017-02-24 11:24 316 查看
  基础练习 2n皇后问题  

时间限制:1.0s   内存限制:512.0MB
      

问题描述

  给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。

输入格式

  输入的第一行为一个整数n,表示棋盘的大小。

  接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。

输出格式

  输出一个整数,表示总共有多少种放法。

样例输入

4

1 1 1 1

1 1 1 1

1 1 1 1

1 1 1 1

样例输出

2

样例输入

4

1 0 1 1

1 1 1 1

1 1 1 1

1 1 1 1

样例输出

0

#include<stdio.h>

#include<string.h>

#include<math.h>

int n,s;

int g[10][10],c[10],b[10];

//数组c为安放黑皇后的数组,b为白皇后。其中下标表示皇后所在行,值为所在列。
void dfs2(int step)
{
int i,j,flag2;
if(step==n+1)//搜索到一种,种数加一
{
s++;
return;//返回到上一层继续寻找下一种安放方法
}
for(i=1;i<=n;i++)
{
if(g[step][i]==0||c[step]==i)//如果不能安放皇后或者已经放了黑皇后,继续尝试下一列
continue;
flag2=1;
b[step]=i;//,否则假设该位置已安放上白皇后,检查是否与step之前的行放置的皇后冲突
for(j=1;j<step;j++)
{
if(b[step]==b[j]||abs(b[step]-b[j])==step-j)
   {
flag2=0;
b[step]=-1;
   break;//若冲突,跳出内层循环,继续尝试下一列
}

}
if(flag2)//否则搜索下一行
dfs2(step+1);
}
return ;//若该行的所有列都不满足,返回到上一次调用的位置
 } 

//安放黑皇后
 void dfs1(int step) //搜索行
 {
 
int i,j,flag1;
 
if(step==n+1)//黑皇后安放完毕,寻找白皇后
 
{
 
dfs2(1);
 
return;
}
for(i=1;i<=n;i++)
{
if(g[step][i]==0)//不能安放皇后,继续寻找
continue;
c[step]=i;//设step,i可以放置

flag1=1;
for(j=1;j<step;j++)//寻找step之前已经安放好的行,安放step,i后是否满足题意
{
if(c[step]==c[j]||abs(c[step]-c[j])==step-j)//若不满足题意
{
flag1=0;
c[step]=-1;//归位
break;//跳出内层循环,尝试下一列
}
}
if(flag1)//若满足题意,安放下一行
dfs1(step+1);

return;
  } 
int main()
{
int i,j;
scanf("%d",&n);
memset(c,-1,sizeof(c));
memset(b,-1,sizeof(b));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&g[i][j]);
s=0;
    dfs1(1);
    printf("%d",s);
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: