题目来源:【JZOJ】
题目描述
在一个 n ∗ n n*n n∗n的国际象棋棋盘上放置 n ( n < = 12 ) n(n<=12) n(n<=12)个皇后,使它们不能互相攻击(即任意两个皇后不能在同一行、同一列或同一对角线上)。试求出第一种(皇后在第 i i i行最靠前的情况下,以后各行也尽量靠前)排列方案,和所有方法。
输入
输入一个数 n ( n < = 12 ) n (n<=12) n(n<=12)
输出
输出所有的排列方案总数。
样例输入
4
样例输出
2
分析:这道题到手之后,可以看出来,这是属于一个图的搜索(似乎是在一本正经的胡说八道,哪里有图了!?)根据题意:“两个皇后不能在同一行、同一列或同一对角线上”,得出三个合法得走法分别是:
i
、
i
+
j
、
i
−
j
+
n
i、i+j、i-j+n
i、i+j、i−j+n,那现在只需要对每个方向做判断和标记即可。
Code:
#include<bits/stdc++.h>//懒得打头文件了,直接Van能头
using namespace std;
int n,total;
bool a[13],b[100],c[100];//三个bool类型得数组,用来做标记
void s(int i)//定义一个无返回值得函数
{
for(register int j=1;j<=n;j++){
if(!a[j]&&!b[i+j]&&!c[i-j+n]){//判断是否标记
a[j]=true;
b[i+j]=true;
c[i-j+n]=true;//往三个方向依次搜索
if(i==n) total++;//如果可行,答案增加
else s(i+1);//不然的话,就进入下一层搜索
a[j]=false;
b[i+j]=false;
c[i-j+n]=false;//回溯一步
}
}
}
int main()
{
scanf("%d",&n);
s(1);//从1开始搜索
printf("%d\n",total);
return 0;
}
嗯这篇blog就到这里了,楼下隐形字,欢迎扫一扫查看↓。。。