基础练习
资源限制
时间限制: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<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
int jj=0;
int pd(int i,int b[],int n,int r)
{
for(int j=0; j<n; j++)
{
if(i/r==b[j]/r||b[j]%r==i%r||abs(i/r-b[j]/r)==abs(i%r-b[j]%r)){
return 0;
}
}
return 1;
}
void put1(int a[],int b[],int c[],int n,int r)
{
if(n==2*r)
{
jj++;
return;
}
if(n<r)
{
int i;
if(n!=0)
i=b[n-1]+1;
else
i=0;
for(;i<r*r;i++)
{
if(a[i]==1&&pd(i,b,n,r))
{
//cout<<n<<' '<<i<<endl;
b[n]=i,a[i]=0;
put1(a,b,c,n+1,r);
b[n]=0,a[i]=1;
}
}
}
else
{
n=n-r;
int i;
if(n!=0)
i=c[n-1]+1;
else
i=0;
for(;i<r*r;i++)
{
if(a[i]==1&&pd(i,c,n,r))
{
//cout<<n+r<<' '<<i<<endl;
c[n]=i,a[i]=0;
put1(a,b,c,r+n+1,r);
c[n]=0,a[i]=1;
}
}
n=n+r;
}
}
int main()
{
int n;
cin>>n;
int a[n*n];
for(int j=0;j<n*n;j++)
cin>>a[j];
int b[n],c[n];
for(int j=0;j<n;j++)
{
b[j]=0;
c[j]=0;
}
put1(a,b,c,0,n);
cout<<jj;
}