N-皇后问题(回溯,递归)
题目:
注意:
对主对角线和副对角线的标记
需要先预处理数据,将1-10的结果计算出来存放在数组中后面需要计算时直接调用
如果直接每一次直接计算的话可能会超时
代码:
#include <stdio.h>
int t;
int num;
bool tag[3][25];//对同列,主对角线,副对角线进行标记
int place[15];//保存放置结果
void chessboard(int n)
{
if(n==t)//如果放好了最后一个棋子,放置方式加一
{
num++;
return;
}
for(int i=0; i<t; i++)//对一行中每一个位置都进行尝试
{
if(!tag[0][i]&&!tag[1][n+i]&&!tag[2][t+n-i-1])
//如果同列,主对角线,副对角线都没有标记(因为我们一行只有一个棋子,所以不用进行标记)
{
tag[0][i]=tag[1][n+i]=tag[2][t+n-i-1]=true;//进行标记
chessboard(n+1);//摆放下一个棋子
tag[0][i]=tag[1][n+i]=tag[2][t+n-i-1]=false;//回溯,消除标记
}
}
}
int main()
{
for(int j=1; j<=10; j++)
{
num=0;
t=j;
chessboard(0);
place[j]=num;//对1-10每一种情况进行计算将结果保存在place数组中
}
int n;
while(scanf("%d",&n))
{
if(n==0)
break;
printf("%d\n",place[n]);
}
return 0;
}
当然这个题目数据比较小,是可以水过去的
#include <stdio.h>
int main()
{
int place[10]={1,0,0,2,10,4,40,92,352,724};
int n;
while(scanf("%d",&n))
{
if(n==0)
break;
printf("%d\n",place[n-1]);
}
return 0;
}