算法实例——N皇后问题(位运算优化)

题目

在一张N∗N的国际象棋棋盘上,放置N个皇后,使得所有皇后都无法互相直接攻击得到,(皇后可以直接攻击到她所在的横行,竖列,斜方向上的棋子),现在输入一个整数N,表示在N∗N的棋盘上放N个皇后,请输出共有多少种使得所有皇后都无法互相直接攻击得到的方案数。 例如下面这样的摆法,是4皇后的一个解 (1代表有皇后,0代表没有)

0 1 0 0
0 0 0 1
1 0 0 0
0 0 1 0

分析

题目的意思是如何在一个N*N的网格中摆上N个棋子,规则是任意两个棋子之间不能同行、同列或者同斜线。

代码

基本实现

def nQueen(n):
    res = 0
    if n >= 4:
        record = [0 for i in range(n)]

        res += process(0, record, n)
    return res

## 递归求解
def process(i, record, n):
    if i == n:
        return 1
    res = 0
    for j in range(n):
        if single(record, i, j):
            record[i] = j
            res += process(i + 1, record, n)
    return res

## 判断该位置是否符合条件
def single(record, i, j):
    for k in range(i):
        if record[k] == j or abs(record[k] - j) == abs(k - i):
            return False
    return True

位运算优化

def nQueen2(n):
    res = 0
    if n >= 4:
        limit = -1 if n == 32 else (1 << n) - 1
        res += process1(limit, 0, 0, 0)
    return res


def process1(limit, col, left, right):
    if col == limit:
        return 1
    a = limit & ~(col | left | right)
    most = 0
    res = 0
    while a != 0:
        most = a & (~a + 1)
        a = a - most
        res += process1(limit, col | most, (left | most) << 1, (right | most) >> 1)

    return res

版权声明:本文为m0_52000372原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。