当前位置:   article > 正文

数据结构学习之栈求解n皇后问题

实验题8:用栈求解n 皇后问题 目的:深入掌握栈应用的算法设计。 内容:编写一个程序

数据结构学习之栈求解n皇后问题

0x1 目的

​ 深入掌握栈应用的算法和设计

0x2 内容

​ 编写一个程序exp3-8.cpp求解n皇后问题。

0x3 问题描述

即在n×n的方格棋盘上,放置n个皇后,要求每个皇后不同行、不同列、不同左右对角线。

要求:(1)皇后的个数n由用户输入,其值不能超过20,输出所有的解。(2)采用类似于栈求解迷宫问题的方法。

0x4 代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <string.h>
  5. #define MaxSize 100000+7
  6. #define maxsize 20+7
  7. using namespace std;
  8. int path[maxsize][maxsize];
  9. int n;
  10. int y_pos[maxsize];
  11. int count=0;
  12. bool judge(int num)
  13. {
  14. for(int i=0;i<num;i++)
  15. {
  16. if(y_pos[i]==y_pos[num] || abs(y_pos[num]-y_pos[i])==num-i)
  17. return false;
  18. }
  19. return true;
  20. }
  21. typedef struct
  22. {
  23. int x;
  24. int y;
  25. int di;
  26. }Box;
  27. typedef struct
  28. {
  29. Box data[MaxSize];
  30. int top;
  31. }StType;
  32. void InitStack(StType *&s)
  33. {
  34. s=(StType *)malloc(sizeof(StType));
  35. s->top=-1;
  36. }
  37. void DestroyStack(StType *&s)
  38. {
  39. free(s);
  40. }
  41. bool GetTop(StType *&s,Box &e)
  42. {
  43. if(s->top==-1)
  44. return false;
  45. e=s->data[s->top];
  46. return true;
  47. }
  48. bool push(StType *&s,Box e)
  49. {
  50. if(s->top==MaxSize-1)
  51. return false;
  52. s->top++;
  53. s->data[s->top]=e;
  54. return true;
  55. }
  56. bool pop(StType *&s,Box &e)
  57. {
  58. if(s->top==-1)
  59. return false;
  60. e=s->data[s->top];
  61. s->top--;
  62. return true;
  63. }
  64. int GetLength(StType *s)
  65. {
  66. return(s->top+1);
  67. }
  68. bool EmptyStack(StType *s)
  69. {
  70. return(s->top==-1);
  71. }
  72. void SetPath(int ex,int ey,int k)
  73. {
  74. int xi=ex;
  75. int yi=ey;
  76. for(int i=0;i<n;i++)
  77. {
  78. path[xi][i]+=k;
  79. path[i][yi]+=k;
  80. }
  81. int x1,x2,y1,y2;
  82. x1=x2=xi;
  83. y1=y2=yi;
  84. while(x1>0&&y1>0)
  85. path[--x1][--y1]+=k;
  86. while(x2<n&&y2<n)
  87. path[x2++][y2++]+=k;
  88. path[xi][yi]-=k*2;
  89. }
  90. void printSolution()
  91. {
  92. for(int i=0;i<n;i++)
  93. {
  94. for(int j=0;j<n;j++)
  95. {
  96. if(y_pos[i]==j)
  97. printf("q");
  98. else
  99. printf("*");
  100. }
  101. printf("\n");
  102. }
  103. printf("\n");
  104. }
  105. void Disp(StType *s)
  106. {
  107. for(int i=0;i<s->top;i++)
  108. printf("\t(%d,%d)",s->data[i].x,s->data[i].y);
  109. }
  110. void SolveQ(int n)
  111. {
  112. int x1,y1,di;
  113. StType *st;
  114. InitStack(st);
  115. Box e;
  116. e.x=0;
  117. e.y=-1;
  118. push(st,e);
  119. while(!EmptyStack(st))
  120. {
  121. GetTop(st,e);
  122. x1=e.x;
  123. y1=e.y;
  124. bool find=false;
  125. if(x1==n)
  126. {
  127. printSolution();
  128. Disp(st);
  129. printf("\n");
  130. count++;
  131. }
  132. while(y1<n-1 && !find)
  133. {
  134. y1++;
  135. y_pos[x1]=y1;
  136. st->data[st->top].y=y1;
  137. if(judge(x1))
  138. {
  139. find=true;
  140. e.x=x1+1;
  141. e.y=-1;
  142. push(st,e);
  143. }
  144. }
  145. if(!find)
  146. {
  147. pop(st,e);
  148. }
  149. //pop(st,e);
  150. }
  151. }
  152. int main()
  153. {
  154. printf("please input n:\n");
  155. scanf("%d",&n);
  156. memset(path,0,sizeof(path));
  157. memset(y_pos,0,sizeof(y_pos));
  158. SolveQ(n);
  159. printf("\n count:%d \n",count);
  160. return 0;
  161. }

0x5 结果

image-20190412092903446

0x6 总结

​ 当时我在写的时候很纠结从0开始的问题,思想肯定是这样子的,先遍历每一行的每一列,然后在回溯。那么就需要做好回溯的标志e.x记录当前在第几行,方便下次回溯到e.x-1,这里唯一需要注意的是判断打印条件,if(x1==n),一开始我以为既然已经让第七行进栈了,那么说明满足,但是后面我理解错了,程序的逻辑是下一行进栈开始的时候y1=-1的,也就是我们要去到第8行才能知道第7行的结果是可以的。

转载于:https://www.cnblogs.com/xq17dog/p/10694116.html

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号