18124 N皇后问题
时间限制:2000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC;VC
Description
有N*N的国际象棋棋盘,要求在上面放N个皇后,要求任意两个皇后不会互杀,有多少种不同的放法?
输入格式
每一个数为T,代表CASE的数量,T<=13
此后,每行一个数N(13>=N>0)
输出格式
每一个CASE,输出对应答案
输入样例
2
4
5
输出样例
2
10
总结:这要题分析可以得到每行只有一个皇后,所以,第几个皇后就代表着第几行,于是,棋盘便可以定义为一个一位数组。在第一个for循环中是在每一列是否能摆放皇后,而第二个for循环来说,是在判断当前这个位置和前面k个皇后位置是否冲突。
还有一个值得思考的就是,第一行的皇后位置是都有被包括的,因为当k=0时,第一个for循环都会进行NQueen()操作,也就包含到了所有的关系!
这里面有个小小的细节,就是呢,j==k,之前我一直觉得for完成循环完后(无break),j应该是等于k-1,但我后来自己开了一个程序来验证后,发现并不是的,在完成for循环后这里的j还会进行+1,因为这是j++(注意和++j的区别)。
#include <iostream>
#include <cmath>
using namespace std;
int N;
int res;
int queenPos[100];
//用来存放算好的皇后位置。最左上角是(0,0) void NQueen( int k);
void NQueen( int k) { //在0~k-1行皇后已经摆好的情况下,摆第k行及其后的皇后
if(k==N)
{
res++;
}
for(int i=0;i<N;i++)
{
int j;
for(j=0;j<k;j++)
{
if(queenPos[j]==i||abs(queenPos[j] - i) == abs(k-j))
//注意这里要判断对角线的情况
break;
}
if(j==k)
{
queenPos[k]=i;
NQueen(k+1);
}
}
}
int main()
{
int c;
cin>>c;
while(c--) {
cin >> N;
res=0;
NQueen(0); //从第0行开始摆皇后
cout << res<<endl;
}
return 0;
}