N皇后问题—初级回溯

N皇后问题,最基础的回溯问题之一,题意简单N*N的正方形格子上放置N个皇后,任意两个皇后不能出现在同一条直线或者斜线上,求不同N对应的解。

提要:N>13时,数量庞大,初级回溯只能保证在N<=13的情况下快速得出答案,重点是数组cur[],表示的是第几行上放的皇后在第几列上,比如cur[1]=2;

表示第一行中的皇后已经放置,且在第一行的第二列上、然后用两个函数判断是否共线、下面是代码...

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstring>
using namespace std;
int cur[16];
int real(int i,int j)//求i-j的绝对值
{
    if (i>j) return i-j;
    else return j-i;
}
int buzaitongyiahang(int i,int j) // 判断不在同一行
{
    for (int k=1; k<i; k++)
        if (cur[k]==j) return 0;
    return 1;
}
int notxie(int i,int j)    //判断不在一条斜线上
{
    for (int k=1; k<i; k++)
        if (real(i,k)==real(j,cur[k])) return 0;
    return 1;
}
int putque(int n,int i)
{
    int ans=0;
    int j;
    if (i==1)
    {
        for (j=1; j<=n; j++)
        {
            cur[i]=j;
            ans+=putque(n,2);
            cur[i]=-1;
        }
    }
    else if (i==n)
    {
        for (j=1; j<=n; j++)
            if (putque(i,j)&&notxie(i,j))
            {
                cur[i]=j;
                return 1;
            }
    }
    else
    {
        for (j=1; j<=n; j++)
            if (buzaitongyiahang(i,j)&&notxie(i,j))
            {
                cur[i]=j;
                ans+=putque(n,i+1);
                cur[i]=3276;
            }
    }
    return ans;
}

void work(int n)
{
    for (int k=1;k<=15;k++) cur[k]=-1;
    printf("%d
",putque(n,1));
}
int main()
{
    int T,N;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&N);
        if (N==1) printf("1
");
        else  work(N);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Lionel002/p/5589512.html