n皇后问题

n*n的棋盘上放n个皇后。最多有多少种放法。

这个题类似于houseblocks,但此题不需要二维数组。用一个一维数组的数值表示行数,下标表示列数。即(x[i], i)。因为要放n个,所以必须一列有一个皇后,因此第几个皇后就放在第几列。
从第一个皇后开始(第一列),放在第一行,放完了以后进行判断,如果前边没有皇后,那么继续放下一个,如果有,放在第二行……用for循环j实现。直到放完了n个皇后,此时放法+1。之后,再回到上一层,即上一层的j变为j的下一个,也就是把上一个皇后再挪到下一行上,再往后进行……当这个皇后已经挪到第n行上以后,再回到上一层,继续进行…… (可行则进,不行则换,换不成则退)
这里的check函数比较巧妙。不用挨着判断行、列、主对角、副对角,假设前边的皇后坐标为(x[k], k), 要判断的为(x[i], i),那么不在主对角:x[k]+k!=x[i]+i,不在副对角:x[k]-k!=x[i]-i。综合:abs(x[k]-x[i])!=abs(k-i) && x[k]!=x[i]。而第几个皇后就在第几列,所以不用判断也知道不会在同一列上。

#include
#include

int n, x[10], sum;
int check(int k)             //某一点放置的坐标为(x[k], k).
{
    int i;
    for(i = 1 ; i < k ; i++)
        if(abs(k-i) == abs(x[k] - x[i]) || x[k] == x[i])
            return 0;
    return 1;
}

void dfs(int i)
{
    int j;
    if(i > n)                       //如果最后一个皇后也放完了,即得到一个可行解。sum+1.
    {
        sum++;
        return;
    }
    else
        for(j = 1 ; j <= n ; j++)
        {
            x[i] = j;                 //将第i个放在第j行上。即把x[i]的坐标改为j。
            if(check(i))               //如果放置的这第i个皇后的前边(行列斜)没有其他皇后,那么继续放置下一个皇后。如果有,则j自加,即把第i个(列坐标为i)放在第j+1行。
                dfs(i+1);
        }
}

int main()
{
    scanf("%d", &n);
    dfs(1);
    if(n == 0)
        sum = 0;
    printf("%d\n", sum);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值