当前位置:   article > 正文

回溯法解决n皇后问题(迭代版)_求解n皇后问题迭代

求解n皇后问题迭代

n皇后问题关键在于judge函数,判断当前的情况是否合法

        1.x[i]==x[k]说明有两个皇后处于同一列,不符合
        2.x[k]-x[i]==k-i:
        由于k-i是固定的,假设k=3,i=2,那么k-i=1,
        如果x[k]-x[i]=1, 说明第k个皇后在第i个皇后右下角
        如果x[k]-x[i]=-1,说明第k个皇后在第i个皇后左下角
        其他情况如k=5,i=3以此类推
        不用考虑第k个皇后在第i个皇后左上角或者右上角的情况
        因为for循环从小到大循环,保证了k是i后面的数 

  1. bool judge(int k)
  2. {
  3. if(k==1) return true;
  4. else
  5. {
  6. if(x[k]<=0) return false;
  7. // 1.x[i]==x[k]说明有两个皇后处于同一列,不符合
  8. // 2.x[k]-x[i]==k-i:
  9. // 由于k-i是固定的,假设k=3,i=2,那么k-i=1,
  10. // 如果x[k]-x[i]=1, 说明第k个皇后在第i个皇后右下角
  11. // 如果x[k]-x[i]=-1,说明第k个皇后在第i个皇后左下角
  12. // 其他情况如k=5,i=3以此类推
  13. // 不用考虑第k个皇后在第i个皇后左上角或者右上角的情况
  14. // 因为for循环从小到大循环,保证了k是i后面的数
  15. for(int i=1;i<k;i++)
  16. if(x[i]==x[k]||x[k]-x[i]==k-i||x[k]-x[i]==i-k)
  17. return false;
  18. return true;
  19. }
  20. }

这个迭代版本的算法模仿了递归版本的算法,因此每一次回退都要”恢复现场“

  1. //恢复现场
  2. x[k]=0;
  3. k=k-1;

完整代码

  1. #include<iostream>
  2. using namespace std;
  3. const int N=1010;
  4. int x[N];//x[i]表示第i个点放在第几列
  5. int n,cnt;
  6. bool judge(int k)
  7. {
  8. if(k==1) return true;
  9. else
  10. {
  11. if(x[k]<=0) return false;
  12. // 1.x[i]==x[k]说明有两个皇后处于同一列,不符合
  13. // 2.x[k]-x[i]==k-i:
  14. // 由于k-i是固定的,假设k=3,i=2,那么k-i=1,
  15. // 如果x[k]-x[i]=1, 说明第k个皇后在第i个皇后右下角
  16. // 如果x[k]-x[i]=-1,说明第k个皇后在第i个皇后左下角
  17. // 其他情况如k=5,i=3以此类推
  18. // 不用考虑第k个皇后在第i个皇后左上角或者右上角的情况
  19. // 因为for循环从小到大循环,保证了k是i后面的数
  20. for(int i=1;i<k;i++)
  21. if(x[i]==x[k]||x[k]-x[i]==k-i||x[k]-x[i]==i-k)
  22. return false;
  23. return true;
  24. }
  25. }
  26. void solve(int k)
  27. {
  28. while(k>=1)
  29. {
  30. while(x[k]<=n-1)
  31. {
  32. x[k]=x[k]+1;
  33. // printf("k=%d,x[k]=%d\n",k,x[k]);
  34. //判断当前位置是否合法
  35. if(judge(k))
  36. {
  37. if(k!=n)
  38. k++;
  39. else if(k==n)
  40. {
  41. cnt++;
  42. printf("--------找到合法解决方案!--------\n");
  43. for(int i=1;i<=n;i++)
  44. printf("%d ",x[i]);
  45. printf("\n");
  46. }
  47. }
  48. }
  49. //恢复现场
  50. x[k]=0;
  51. k=k-1;
  52. }
  53. }
  54. int main()
  55. {
  56. cin>>n;
  57. for(int i=1;i<=n;i++)//虽然全局变量初始化过了,这里显式初始化
  58. x[i]=0;
  59. solve(1);
  60. printf("共有%d种解决方案!\n",cnt);
  61. return 0;
  62. }

运行结果(n=8):

标准答案:

对于N从1到8的N皇后问题,以下是每个N值对应的解决方案数量:

  • N=1: 1种解决方案
  • N=2: 0种解决方案
  • N=3: 0种解决方案
  • N=4: 2种解决方案
  • N=5: 10种解决方案
  • N=6: 4种解决方案
  • N=7: 40种解决方案
  • N=8: 92种解决方案

对照标准答案,我们可以知道这个算法是正确的

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

闽ICP备14008679号