题目:N皇后问题(待验证)

题解

  1. 根据皇后不能同行同列的性质可以知道,要在N*N棋盘上摆N个皇后则每行最多一个皇后,所以在暴力解的时候不需要每个皇后都遍历N *N种可能,只需要对该皇后对应行的N种可能遍历就行了(这里一层递归就代表一行,也就是一个皇后,以递归形参i来控制)。
  2. 直接用一个二维flag数组来标志棋盘上哪些格子可以放皇后,而每当在(i,j)放入一个皇后就要将其同排同列和上下斜线的格子flag置1,分别对应k = = i || r = = j || (k+r) = = (i+j) || (k-r) = =(i-j)。

题目

问题 F: N皇后问题
时间限制: 1 Sec  内存限制: 128 MB
提交: 1018  解决: 581
[提交][状态][讨论版]
题目描述
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

输入
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。


输出
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。


样例输入
1
8
5
0
样例输出
1
92
10

代码块

#include <iostream>
using namespace std;

int num;

void function(int i, int n, int flag[100][100])
{
    if(i==n)
        num++;
    else
    {
        for(int j=0; j<n; j++)
        {
            if(!flag[i][j])
            {
                int flag1[100][100];//只需要将改变了的flag数组传入下一层递归,但并不需要改变这层递归中的flag数组,所以可以新建一个flag1作为改变了的flag的镜像传入下层。
                for(int k=0; k<n; k++)
                {
                    for(int r=0; r<n; r++)
                    {
                        if(k==i || r==j || (k+r)==(i+j) || (k-r)==(i-j))
                            flag1[k][r] = 1;
                        else
                            flag1[k][r] = flag[k][r];
                    }
                }
                function(i+1, n, flag1);
            }
        }
    }

}

int main(void)
{
    int n;
    while(cin>>n)
    {
        if(n)
        {
            num = 0;
            int flag[100][100];
            for(int i=0; i<n; i++)
                for(int j=0; j<n; j++)
                    flag[i][j] = 0;
            function(0, n, flag);
            cout<<num<<endl;
        }
        else
            return 0;
    }
}
上一篇:Oracle中imp命令使用出错——未知命令开头


下一篇:C# Visual Studio CRUD对数据库增删改查的实现