1269: 基础练习 2n皇后问题

时间:2023-02-12 22:42:45

1269: 基础练习 2n皇后问题

时间限制: 1 Sec  内存限制: 512 MB
[ 提交][ 状态][ 讨论版]

Problem Description

给定一个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>
int number;
int arr[100][100];
int bQueen[100];
int wQueen[100];
int count=0;
int BlackQueen(int line)
{
	int temp,i;
	for(i=0;i<line-1;i++)
	{
		temp=bQueen[i]-bQueen[line-1];
		if(temp==0 || temp==line-1-i || -temp==line-1-i)
			return 0;		//0 == judge代表在同一列,judge == pos - 1 - i代表在斜率为1的直线上,-judge == pos - 1 - i代表在斜率为-1的直线上 
	}	
	if(line==number)			//皇后的个数等于列数
	{
		count++;
		return 0;
	}
	for(i=0;i<number;i++)			//判断每一列 
	{
		if(arr[line][i] && wQueen[line]!=i)
		{
			bQueen[line]=i;
			BlackQueen(line+1);
		}
	}
}
int WhiteQueen(int line)
{
	int temp,i;
	for(i=0;i<line-1;i++)
	{
		temp=wQueen[i]-wQueen[line-1];
		if(temp==0 || temp==line-1-i || -temp==line-1-i)
			return 0;
    }
	if(line==number)			//皇后的个数等于列数
	{
		BlackQueen(0);			//判断第0行
		return 0;
	}
	for(i=0;i<number;i++)			//判断每一列 
	{
		if(arr[line][i])
		{
			wQueen[line]=i;
			WhiteQueen(line+1);
		}
	}
}
int main()
{
	int i,j;
	scanf("%d",&number);
	for(i=0;i<number;i++)
	{
		for(j=0;j<number;j++)
		{
			scanf("%d",&arr[i][j]);
		}
	}
	WhiteQueen(0);			//判断第0行
	printf("%d\n",count);
	return 0;
}


#include<iostream>
using namespace std;
#define N   100
int wq[N];           //whitequeen,白皇后位置
int bq[N];           //blackqueen,黑皇后位置
int cb[N][N];        //chessboard,棋盘
int num;             //皇后数目
int count = 0;       //不同放置情况计数
int bqueen(int pos)  //黑色皇后放置
{
    int i;
    for(i = 0; i < pos -1; i++)
    {
        int judge = bq[i] - bq[pos-1];
        if(0 == judge || judge == pos - 1 - i || -judge == pos - 1 - i)
            return 0;
    }
    if(pos == num)
    {
        count++;
        return 0;
    }

    for(int i = 0; i < num; i++)
    {
        if(i != wq[pos] && cb[pos][i])
        {
            bq[pos] = i;
            bqueen(pos+1);
        }
    }
}
int wqueen(int pos) //白色皇后放置
{
    int i;
    for(i = 0; i < pos -1; i++)
    {
        int judge = wq[i] - wq[pos-1];                                          //由于是一行一行判断的,因此不可能在同一行 
        if(0 == judge || judge == pos - 1 - i || -judge == pos - 1 - i)         //0 == judge代表在同一列 
            return 0;                                                           //judge == pos - 1 - i代表在斜率为1的直线上 
    }                                                                           //-judge == pos - 1 - i代表在斜率为-1的直线上
    if(pos == num)                              //皇后的个数等于列数 
    {
        bqueen(0);
        return 0;
    }

    for(int i = 0; i < num; i++)//判断每一列 
    {
     if(cb[pos][i])
        {
            wq[pos] = i;
            wqueen(pos+1);      //判断下一行 
        }

    }
}
int main()
{
    cin>>num;
    for(int i =0; i < num; i++)
        for(int j = 0; j < num; j++)
            cin>>cb[i][j];
    wqueen(0);               //判断第0行 
    cout<<count;
    return 0;
}