N-皇后问题(回溯,递归)

题目:

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;
}