1295 N皇后问题
时间限制: 2 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题解
题目描述 Description
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。
输入描述 Input Description
给定棋盘的大小n (n ≤ 13)
输出描述 Output Description
输出整数表示有多少种放置方法。
样例输入 Sample Input
8
样例输出 Sample Output
92
数据范围及提示 Data Size & Hint
n<=13
(时限提高了,不用打表了)
#include <stdio.h>
#include <iostream>
int map[13][2];//MAX=13
int peg[13][13];//
int countway=0;
void nQueen(int i, int j, int num, int n, int peg[13][13], int map[13][2]);
int main(){
int j;
int n;
scanf("%d",&n);
for(j=0;j<n;j++){
nQueen(0, j, 0, n, peg, map);// 0,0 -> 0,n-1 /step 0 /max n/
}
printf("%d\n",countway);
return 0;
}
void nQueen(int i, int j, int num, int n, int peg[13][13], int map[13][2]){
//printf("此次调用的是节点:(%d %d) num=%d\n",i,j,num);
//for(int l=0;l<n;l++){ //输出标记矩阵
// for(int d=0;d<n;d++){
// printf("%d ",peg[l][d]);
// }
// printf("\n");
//}
//printf("\n\n");
//for(int jt=0;jt<num;jt++){ //test
// printf("(%d,%d) \n",map[jt][0],map[jt][1]);
//}
int sign=0;
for(int m=0;m<n;m++){//判断条件
if(peg[m][j]!=0){// col
sign=1;
break;
}
if(peg[i][m]!=0){//line
sign=1;
break;
}
if(m!=0){//斜着的不存在 等于0的
if(i-m>=0 && j-m>=0 && peg[i-m][j-m]!=0){
sign=1;
break;
}
if(i-m>=0 && j+m<n && peg[i-m][j+m]!=0){
sign=1;
break;
}
if(i+m<n && j-m>=0 && peg[i+m][j-m]!=0){
sign=1;
break;
}
if(i+m<n && j+m<n && peg[i+m][j+m]!=0){
sign=1;
break;
}
}
}
if(sign==1){
//if(i==0 && j==2){
// printf("0,2 0,2 0,2 0,2 \n\n\n");
//
//}
return;
}else{
//printf("(%d %d) num=%d\n",i,j,num);//test
peg[i][j]=1;
map[num][0]=i;map[num][1]=j;
num++;
//for(int jt=0;jt<num;jt++){ //test
// printf("(%d,%d) \n\n",map[jt][0],map[jt][1]);
//}
//
if(num==n){// length enough
countway++;
/*
printf("\n");
for(int jt=0;jt<n;jt++){
printf("(%d,%d) ",map[jt][0],map[jt][1]);
//peg[map[jt][0]][map[jt][1]]=0;
;
}
printf("\n");
*/
peg[i][j]=0;//走完释放 release
return;
}
//
for(int k=0;k<n;k++){
if(k==j || k==j-1 || k==j+1){
continue;
}
nQueen(i+1, k, num, n, peg, map);
}
//
peg[i][j]=0;//走完释放 release
}
}