当前位置:   article > 正文

DFS(深度优先搜索)_void dfs

void dfs

DFS(depth-first search)是一种搜索手段,它从某一个状态开始,不断转移,直到状态无法转移回退到前一步,继续转移到其他的状态,不断重复,知道找到它的解。根据这种性质,DFS用递归实现比较简单。

我们来看几道题来理解一下dfs.

第一道题就是求全排列

  1. #include <iostream>
  2. using namespace std;
  3. int a[10],flag[10],n;
  4. void dfs(int x){
  5. if(x==n+1){ //求n个数字的全排列,当x超过n输出结果
  6. for(int i=1;i<=n;i++){
  7. cout<<a[i]<<" ";
  8. }
  9. cout<<endl;
  10. return; //输出之后返回上一个状态
  11. }
  12. for(int i=1;i<=n;i++){
  13. if(flag[i]==0){
  14. a[x]=i; //将数组赋值之后,把这个数字打上一个标记
  15. flag[i]=1;
  16. dfs(x+1); //调用到下一层函数
  17. flag[i]=0; //取消标记
  18. }
  19. }
  20. return; //返回到上一个状态
  21. }
  22. int main(){
  23. cin>>n;
  24. dfs(1);
  25. return 0;
  26. }

通过这个题,我们可以总结出一个DFS的基本模板

  1. bool judge(/*参数*/){
  2. if(/*判断条件*/){
  3. return false;
  4. }
  5. return true;
  6. }
  7. void dfs(/*参数*/){
  8. /*判断是否是边界*/
  9. {
  10. /*输出*/
  11. }
  12. return;
  13. /*循环*/{
  14. /*判断是否满足条件*/
  15. /*标记*/
  16. dfs(/*下一个状态*/)
  17. /*去掉标记*/
  18. }
  19. }

第二道题,是洛谷里的点这里

 

输入样例:

10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

输出样例:3

  1. //从任意w开始,不停地把邻接的部分用'.'替换,换了几次就证明有几个水洼
  2. #include <iostream>
  3. using namespace std;
  4. char a[101][101];
  5. int n,m;
  6. void dfs(int x,int y){
  7. a[x][y]='.';
  8. for(int dx=-1;dx<=1;dx++){
  9. for(int dy=-1;dy<=1;dy++){
  10. int nx=x+dx;
  11. int ny=y+dy;
  12. if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]=='W'){
  13. dfs(nx,ny);
  14. }
  15. }
  16. }
  17. return;
  18. }
  19. int sum;
  20. int main(){
  21. cin>>n>>m;
  22. for(int i=0;i<n;i++){
  23. for(int j=0;j<m;j++){
  24. cin>>a[i][j];
  25. }
  26. }
  27. for(int i=0;i<n;i++){
  28. for(int j=0;j<m;j++){
  29. if(a[i][j]=='W'){
  30. dfs(i,j);
  31. sum++;
  32. }
  33. }
  34. }
  35. cout<<sum;
  36. }

最后一题,就是大名鼎鼎的八皇后问题点这里

其实我的代码是无法ac的,最后一个点会超时,还需要自己改进一下。

  1. #include <iostream>
  2. using namespace std;
  3. int a[14][14];
  4. int n,cnt;
  5. bool pd(int x,int y,int n){ //判断皇后是否危险
  6. for(int i=1;i<=n;i++){ //判断行
  7. if(a[i][y]==1){
  8. return false;
  9. }
  10. }
  11. for(int i=x,j=y;i>=1&&j>=1;i--,j--){ //判断对角线
  12. if(a[i][j]==1){
  13. return false;
  14. }
  15. }
  16. for(int i=x,j=y;i>=1&&j<=n;i--,j++){ //判断另一条对角线
  17. if(a[i][j]==1){
  18. return false;
  19. }
  20. }
  21. return true;
  22. }
  23. void dfs(int x){
  24. if(x==n+1){
  25. if(cnt<3){
  26. for(int i=1;i<=n;i++){
  27. for(int j=1;j<=n;j++){
  28. if(a[i][j]==1){
  29. if(i==n){
  30. cout<<j;
  31. }else{
  32. cout<<j<<" ";
  33. }
  34. }
  35. }
  36. }
  37. cout<<endl;
  38. }
  39. cnt++;
  40. return;
  41. }
  42. for(int j=1;j<=n;j++){
  43. if(pd(x,j,n)){
  44. a[x][j]=1;
  45. dfs(x+1);
  46. a[x][j]=0;
  47. }
  48. }
  49. }
  50. int main(){
  51. cin>>n;
  52. dfs(1);
  53. cout<<cnt;
  54. return 0;
  55. }

主要参考的是《挑战程序设计竞赛》

和一些大佬的文章点这里,大佬写的比我好很多。我的csdn可能记录的意义大于其他的意义啦。

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

闽ICP备14008679号