http://acm.hdu.edu.cn/showproblem.php?pid=2553
第一种方法,需打表,否则超时
#pragma warning (disable:4786)
#include<iostream>
using namespace std;
int used_column[12]; //标记列是否被用过
int used_Ldia[102],used_Rdia[102]; //标记对角线是否被用过
int n,cc,result;
//返回该元素所在左对角线最左上角的元素坐标
int getLIndex ( int row, int column ){
if( row > column ){
return ( row - column ) * n;
}
else {
return ( column - row );
}
}
//返回该元素所在右对角线最右上角的元素坐标
int getRIndex( int row, int column ){
if( row + column > n - 1 ){
return ( row + column - n + 1 ) * n + n -1;
}
else {
return ( row + column );
}
}
//深搜
void DFS( int row ){
int i;
for( i = 0; i < n; i ++ ){
int l_index = getLIndex ( row, i );
int r_index = getRIndex ( row, i );
//所在列、所在左右对角线都未被使用时,可尝试在该处放置皇后
if( used_column[i] == 0 && used_Ldia[l_index] ==0 && used_Rdia[r_index] ==0 ){
cc ++; //标记当前总共放置的皇后数
if( cc == n )
result ++; //倘若当前总共放置的皇后数达到了n,则放置策略数+1
else{
used_column[i] = 1;
used_Ldia[l_index] = 1;
used_Rdia[r_index] = 1;
DFS( row + 1 ); //递归求解
//恢复状态
used_column[i] = 0;
used_Ldia[l_index] = 0;
used_Rdia[r_index] = 0;
}
//恢复状态
cc --;
}
}
}
int main(){
int i,j, f[11];
//打表,否则超时
for( n = 1; n <= 10; n ++ ){
memset( used_column, 0, sizeof( used_column ) );
memset( used_Ldia, 0, sizeof( used_Ldia ) );
memset( used_Rdia, 0, sizeof( used_Rdia ) );
cc = result = 0;
DFS(0);
f[n] = result;
}
while( scanf( "%d", &n ) && n ){
printf( "%d\n", f[n] );
}
return 0;
}
#pragma warning (disable:4786)
#include<iostream>
using namespace std;
int main(){
int f[11] = {0,1,0,0,2,10,4,40,92,352,724};
int n;
while( scanf( "%d", &n ) && n ){
printf( "%d\n", f[n]);
}
return 0;
}