N后问题之回溯法求解

题目:在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。 

对于给定的N,求出有多少种合法的放置方法。

同一行,同一列:由题可知,N个皇后只能每行放一个,因此采用n元组x[1:n]表示n后问题的解,其中x[i]表示皇后i放在第i行的第x[i]列。由于不允许将两个皇后放在同一列上,所以x[i]互不相同。 
处在与棋盘边框成45角的斜线上:假设存在a(i,x[i]),b(k , x[k])我们可知ab两点在同意对角线即斜率为正负一的情况下应满足 

i-k=x[i]-x[k]或 i-k=x[k]-x[i]; 由此可得| i-k | = | x[i]-x[k] | 

/*
用n元组x[1:n]表示n后问题的解。x[i]表示皇后i放置在棋盘的第i行的第x[i]列
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int n, x[1000]={0};
long sum;

/*
判断第k个后能不能放在x[k]处
两个皇后不能放在统一斜线上:
若2个皇后放置的位置分别是(i,j)和(k,l),
且 i-j = k -l 或 i+j = k+l,则说明这2个皇后处于同一斜线上。
*/

void OutPut()
{
	int i; 
    for (i = 1; i <= n; ++i)
        printf("(%d, %d) ", i, x[i]);
    printf("\n");
}

int Place(int k)
{
	int j;
    for ( j = 1; j < k; ++j)
        if (abs(k - j) == abs(x[k] - x[j]) || x[j] == x[k])
            return 0;
    return 1;
}

void BackTrack1(int t)
{
	int i;
    //如果t>n说明已经完成一次放置
    if (t > n)
    {
        sum++;
        OutPut();
    }
    else
    {
        for ( i = 1; i <= n; ++i)
        {
            x[t] = i;
            if (Place(t))                   //可以放在i位置处,则继续搜索
                BackTrack1(t + 1);
        }
    }
}


int main()
{
    int nn;
    printf("请输入皇后的个数nn:");
    scanf_s("%d", &nn);
    n = nn;
    sum = 0;
    BackTrack1(1);
    printf("%d\n", sum);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值