八皇后问题初始思路python_Python 学习笔记(一)10行代码解决八皇后问题

不引入标准库和第三方库,不用分号将多行代码写在一行,再10行代码之类求出八皇后问题的所有解。

---------------------------------------------------------------------------------------

输出结果为列表l,l[i]表示第i+1行的皇后应放置的列序号。l的初始值是[0]*8,如果第1行的皇后放置在第一列,那么输出值中l[0]=1。

思路图:

l[0] l[1] l[2] l[3] l[4] l[5] l[6] l[7]

i |

k |

m |

从第1行开始一次放置皇后,

指针i用于标定现在正在放置哪一行的皇后,当放置完成后,指针i向后移动一位(如放置完第6行,指针i从l[5]移动到l[6],并开始放置第7行的皇后)。

指针k用于检验第i+1行的皇后是否与第k+1行的皇后在同一列或同一条直线上。如果不满足条件,将i指针所指的元素加1(将第i+1行的皇后向右移动一列),k指针归0(重新检验)。

指针m用于检验各元素是否溢出,因为棋盘只有8列,所以各元素的值只能取1到8,如果前i行的皇后放置得不好,可能造成在第i+1行,不论把皇后放在哪一列,都不能满足条件。这种情况下,按照对指针k和指针i的定义,元素l[i]的值会超过8。因此,当最终确定l[i]的值后,指针m从l[i]开始,检验元素是否大于8,如果没有,m向前移以为(这个操作貌似不必要,以后看看可不可以在不增加代码行数的情况下省略);如果有,将该元素归零后,m向前移动一位,给将前一位元素加一(即方向第i+1行放不了皇后,把第i行皇后向右移动一列,再看看能不能放得下),然后继续检查这个元素是否大于8(如果第i行的元素本身就在第8行了,那么只能再把这一行的皇后重新放置,并把第i-1行的皇后右移一位)。当指针m移到某个元素,给该元素加1后,检测到该元素没有大于8,将指针i移动至这个位置,继续进行前面两个步骤。

输出八皇后问题第一个解的代码:

l, i = [0]*8, 0

while i < 8:

k, l[i] = 0, l[i] + 1

while k < i:

if l[i] == l[k] or abs(l[i] - l[k]) == i - k: l[i], k = l[i] + 1, -1

k += 1

i += 1

for m in range(i - 1, 0, -1):

if l[m] > 8: l[m], i = 0, m - 1

print(l)

输出八皇后问题所有解的代码:

l, i = [0]*8, 0

while l[0] < 9:

k, l[i] = 0, l[i] + 1

while k < i:

if l[i] == l[k] or abs(l[i] - l[k]) == i - k: l[i], k = l[i] + 1, -1

k += 1

for m in range(i, 0, -1):

if l[m] > 8: l[m], i = 0, m - 2

if i < 7: i += 1

else: print(l)

这两个代码的区别在于:

对于第一个脚本,当确定第8行皇后的位置后(确定l[7]的值后),将指针i移出列表索引的范围,因此不满足第2行的判定条件,循环结束。然后输出列表l

l[0] l[1] l[2] l[3] l[4] l[5] l[6] l[7]

i |

k |

m |

对于第二个脚本,当确定第8行皇后的位置后(确定l[7]的值后),输出列表值(触发第10行else条件),将指针i不动。继续循环,按要求继续移动3个指针。注意到按照我所给定的条件移动指针和更新数值,当找完8皇后问题的所有解后,l[0]必将溢出正常范围,因此,我们将循环结束的条件设置为l[0]>=9。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值