方法一:
#include <stdio.h>
#define NUMS 10
/*输入的数字1---10*/
int N;
/*棋盘*/
int chessboard[11][11];
/* 用来记录拜访数目 */
int cal;
/*
检查皇后放置此行此列是否可以,可以返回1,不可以返回0
此递归是一行一行找的,K是棋盘的长度
*/
int dfs_check(int row,int column,int k)
{
/* 说明已经到了棋盘的界外,前边都符合了 */
if(row>k)
{
cal++;
return 1;
}
/* 正上方是否有皇后*/
for(int i = 1; i < row; i++)
/* 如果有皇后则返回不能放置这里返回0*/
if(chessboard[i][column] == 1)
return 0;
/* 左右上方45度角检查是否可以*/
/* 左上方*/
for(int i=row-1,j=column-1;i>0&&j>0;i--,j--)
if(chessboard[i][j] == 1)
return 0;
/* 右上方*/
for(int i=row-1,j=column+1;i>0&&j<=k;i--,j++)
if(chessboard[i][j] == 1)
return 0;
/*标记这个位置成功了*/
chessboard[row][column] = 1;
/*进行下一行搜索*/
for(int i=1;i<=k;i++)
if(dfs_check(row+1,i,k)=1)
break;
chessboard[row][column] = 0;
return 0;
}
int main()
{
int i,j,k;
int count[11];
/*打表*/
for(k=1;k<=NUMS;k++)
{
count[k] = 0;
cal = 0;
/*首先将棋盘初始化全部置为0*/
for(i=0;i<=NUMS;i++)
for(j=0;j<=NUMS;j++)
chessboard[i][j]=0;
for(i=1;i<=k;i++)
dfs_check(1,i,k);
count[k] = cal;
}
while(scanf("%d",&N)!=EOF&&N!=0)
printf("%d\n",count[N]);
return 0;
}
方法二:
回溯法:
#include <iostream> using namespace std; int col[11],dia[21],evil[21]; int n,sum,s[11]; void DFS(int x) { int i; if(x==n+1) { sum++; return; } for(i=1;i<=n;i++) { if(!col[i] && !dia[x+i] && !evil[10+i-x]) { col[i]=dia[x+i]=evil[10+i-x]=1; DFS(x+1); col[i]=dia[x+i]=evil[10+i-x]=0; } } } int main() { memset(s,0,sizeof(s)); while(cin>>n&&n) { if(!s[n]) { memset(col,0,sizeof(col)); memset(dia,0,sizeof(dia)); memset(evil,0,sizeof(evil)); sum=0; DFS(1); s[n]=sum; } cout<<s[n]<<endl; } }