1314: n皇后问题(2013年校赛决赛)

题目描述 N皇后问题相信大家都早就听过,就是求一个nn的国际象棋棋盘中,放n个皇后,让每个皇后不互相攻击,问有多少种符合要求放置方法。国际象棋中的皇后可以攻击同一行,同一列和同一斜线上的棋子,也就是说要求的是nn的国际象棋棋盘中,任何两个皇后不放在同一行或同一列或同一斜线上。

这次我们加多一个条件:规定了棋盘上某些格子不能放皇后。

在这种情况下计算有多少种符合要求的放置方法。

输入

输入包含多组测试样例。每组测试样例的第一行有两个数字n和k(4<=n<=10, 0 <= k <= n*n),接下来会跟着k行输入,每行输入两个整数(x,y)表示不能放棋子的位置(X,Y坐标都是从1开始,以最左上角的格子坐标为(1,1)为标准)。

输出

对每个测试样例,输出符合要求的放置方法数量。

样例输入
4 0
4 1
2 1
样例输出
2
1
#include<iostream>
#include<vector>
using namespace std;

int count = 0;
int isCorrect(int n,int m,int i, int j, vector<vector<int> > Q,vector<vector<int> > Else)
{
    int s, t;
    for(s=i,t=0; t<n; t++)
        if(Q[s][t]==1 && t!=j)
            return 0;//判断行
    for(t=j,s=0; s<n; s++)
        if(Q[s][t]==1 && s!=i)
            return 0;//判断列
    for(s=i-1,t=j-1; s>=0&&t>=0; s--,t--)
        if(Q[s][t]==1)
            return 0;//判断左上方
    for(s=i+1,t=j+1; s<n&&t<n;s++,t++)
        if(Q[s][t]==1)
            return 0;//判断右下方
    for(s=i-1,t=j+1; s>=0&&t<n; s--,t++)
        if(Q[s][t]==1)
            return 0;//判断右上方
    for(s=i+1,t=j-1; s<n&&t>=0; s++,t--)
        if(Q[s][t]==1)
            return 0;//判断左下方
        //排除特定情况
        for (int s = 0; s < m; ++s)
        {
                if(Else[s][0]==i && Else[s][1]==j)
                    return 0;
        }

    return 1;//否则返回
}

void Queue(int n,int m,int j, vector<vector<int> > Q,vector<vector<int> > Else)
{
    int i,k;
    if(j==n){//递归结束条件
//        for(i=0; i<n; i++){
//                //得到一个解,在屏幕上显示
//            for(k=0; k<n; k++)
//                printf("%d ", Q[i][k]);
//            printf("\n");
//        }
//        printf("\n");
        count++;
        return ;
    }
    for(i=0; i<n; i++){
        if(isCorrect(n,m,i, j, Q,Else)){//如果Q[i][j]可以放置皇后
            Q[i][j]=1;//放置皇后
            Queue(n,m,j+1, Q,Else);//递归深度优先搜索解空间树
            Q[i][j]=0;//这句代码就是实现回溯到上一层
        }
    }
}

int main()
{
    int n,k;
    while(cin>>n>>k){
                vector<vector<int> > Else(k,vector<int>(2));
                for (int i = 0; i < k; ++i)
                {
                        for (int j = 0; j < 2; ++j)
                        {
                                cin>>Else[i][j];
                                Else[i][j] -= 1;
                        }
                }
        vector<vector<int> > Q(n,vector<int>(n,0));
       // Q[1][0]=1;
        Queue(n,k,0, Q,Else);
                cout<<count<<endl;
                count=0;

    }
    return 0;
}