当前位置:   article > 正文

Python蓝桥杯练习13——n皇后问题_有一个n*n的矩阵方格和n个棋子,现在需要将n个棋子按要求放置到矩阵方格中。 要求

有一个n*n的矩阵方格和n个棋子,现在需要将n个棋子按要求放置到矩阵方格中。 要求

【题目描述】

有一个N*N的矩阵棋盘和N个棋子,现在需要将N个棋子按要求放置在矩阵方格中。

要求:

1、任意两颗棋子不能在同一行

2、任意两个棋子不能在同一列

3、任意两个棋子不能在同一对角线上(下面的红线都是对角线)

根据以上要求,问N个棋子放置到N*N矩阵中有多少种放置方案?

【输入描述】

输入一个正整数N(1<N<11),表示N*N的矩阵方格和N个棋子数量。

【输出描述】

输出N个棋子按要求放置到N*N的矩阵中,有多少种放置方案?

【解题思路】

这要用到dfs来做

首先放置一颗棋子,从第一行开始放置,放置后该行就不能放置其他棋子来,然后每一行放的棋子通过一列一列的方式去检查是否可以放置,跳转到下一行,依次类推,如果下一行都标记不能放置的话,则回溯到上面的操作,依次进行向下标记;如果标记到最后一行,则统计次数,再清空矩阵,直到全部走完。

因为执行的每一趟操作都是类似的,所以可以增加一个递归来计算

设置一个函数,递归的开始条件从第一行开始,可以放置,则跳转到下一行。。。

递归的退出条件是:最后一行,或者下一行没有可以走到点的时候退出

图解

1.首先在第一行第一列放置一个棋子,将所在的对角线,行和列都标记不能放置。 

2.接着跳转到第二行,重复第一步的操作

3.当跳转到下一行的时候,发现都标记了不能放置,则表示无法走通,这一趟不行,回溯到上一步,清空第二部的所有标记,进行另外一个点的放置。

4.接着再跳转到第三行,再进行标记,标记后发现第四行 也以及不可放置,所以这条路也走不通,则清空,回溯到上面新的点再进行操作,以此类推。直到找到能标记到最后一行的点,计数。

直到走到这步才算完整的一条路,得出第一条摆放方式

 


【代码运算】 

  1. n=4
  2. #用来表示放置的位置(下标表示第几行,数值表示第几列)
  3. # ->place[1]=2 表示在第二行第三列标记了数
  4. place = [0 for _ in range(n)]
  5. #用于表示第n列是否被标记 -> flag[1]=1 表示第2列被标记为1
  6. flag=[0 for _ in range(n)]
  7. #表示对角线是否被标记
  8. d1=[0 for _ in range(2*n-1)]#上对角线 行加上列
  9. d2=[0 for _ in range(2*n-1)]#下对角线 行减列加n减1
  10. #计数
  11. count=0
  12. def search(row):#行
  13. global count #标记全局变量
  14. for col in range(n):
  15. if flag[col]==0 and d1[row+col]==0 and d2[row-col+n-1]==0:# 0表示没有被标记
  16. place[row] = col #在第row行第col列标记
  17. #列,对角线标记不能X
  18. flag[col]=1
  19. d1[row+col]=1
  20. d2[row-col+n-1]=1
  21. #如果不是最后一行,继续寻找
  22. if row<n-1:
  23. search(row+1)
  24. else:
  25. count+=1
  26. #最后一行执行结束,清空,继续寻找下一个
  27. flag[col]=0
  28. d1[row+col]=0
  29. d2[row-col+n-1]=0
  30. search(0) #从第一行开始寻找
  31. print(count) #2

上对角线——一共有2*n-1条  可以观察到,行加列=对角线上的值

 下对角线——也是2*n-1条,计算对角线上的值是——row-col+n-1 


 如果想要打印结果,只需要增加一个打印的函数,在每次统计次数时加一个打印即可

【运行代码】

  1. n=4
  2. #用来表示放置的位置(下标表示第几行,数值表示第几列)
  3. # ->place[1]=2 表示在第二行第三列标记了数
  4. place = [0 for _ in range(n)]
  5. #用于表示第n列是否被标记 -> flag[1]=1 表示第2列被标记为1
  6. flag=[0 for _ in range(n)]
  7. #表示对角线是否被标记
  8. d1=[0 for _ in range(2*n-1)]#上对角线 行加上列
  9. d2=[0 for _ in range(2*n-1)]#下对角线 行减列加n减1
  10. #计数
  11. count=0
  12. #打印函数
  13. def printf(place):
  14. #创建一个n行n列的矩阵
  15. for i in range(n):
  16. for j in range(n):
  17. if place[i]==j:
  18. print('*',end=' ')
  19. else:
  20. print('0',end=' ')
  21. print() #每行换行
  22. print() #每个矩阵换行
  23. def search(row):#行
  24. global count #标记全局变量
  25. for col in range(n):
  26. if flag[col]==0 and d1[row+col]==0 and d2[row-col+n-1]==0:# 0表示没有被标记
  27. place[row] = col #在第row行第col列标记
  28. #列,对角线标记不能X
  29. flag[col]=1
  30. d1[row+col]=1
  31. d2[row-col+n-1]=1
  32. #如果不是最后一行,继续寻找
  33. if row<n-1:
  34. search(row+1)
  35. else:
  36. count+=1
  37. #打印
  38. printf(place)
  39. #最后一行执行结束,清空,继续寻找下一个
  40. flag[col]=0
  41. d1[row+col]=0
  42. d2[row-col+n-1]=0
  43. search(0) #从第一行开始寻找
  44. print(count) #2

【运行结果】

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/64098
推荐阅读
相关标签
  

闽ICP备14008679号