当前位置:   article > 正文

DFS合集(蓝桥杯C/C++)(随时更新,更新时间:2023.3.6)_蓝桥杯c++dfs

蓝桥杯c++dfs

目录

1  数的全排列(模板)

2  n皇后问题

3  2n皇后问题

4  车的放置

5  粘木棍

6  24点

7  五星填数


1  数的全排列(模板)

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int a[10]={1,2,3,4,5,6,7,8,9,10};
  4. int b[10];
  5. bool vis[10];
  6. void dfs(int s)
  7. {
  8. if(s==6)
  9. {
  10. for(int i=0;i<6;i++)
  11. {
  12. cout<<b[i]<<' ';
  13. }
  14. cout<<endl;
  15. return;
  16. }
  17. for(int i=0;i<6;i++)
  18. {
  19. if(!vis[i])
  20. {
  21. vis[i]=true;
  22. b[s]=a[i];
  23. dfs(s+1);
  24. vis[i]=false;
  25. }
  26. }
  27. }
  28. int main()
  29. {
  30. dfs(0);
  31. return 0;
  32. }

n皇后问题

特点:充分运用全排列知识,每一行只能放一个皇后,全排列保证每一列只能出现一个皇后,斜线再进行后续处理

2n皇后问题

特点:在n皇后的基础上需要再次运用全排列,属于嵌套搜索

原题:

2n皇后问题(蓝桥杯基础练习C/C++)_菜只因C的博客-CSDN博客_2n皇后问题蓝桥杯2n皇后问题(蓝桥杯基础练习C/C++)https://blog.csdn.net/m0_71934846/article/details/128772257代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int mp[9][9];//初始化地图
  4. bool visblack[9];//黑皇后是否用到
  5. bool viswhite[9];//白皇后是否用到
  6. int black[9],white[9];//皇后放到第几列 *解释1*
  7. int ans;//答案
  8. int cnt,cnt1,cnt2,n,jishu[30],temp;//计数用
  9. int j,i;//循环变量
  10. void dfswhite(int p)//后放
  11. {
  12. if(p==n+1)//设置边界
  13. {
  14. cnt=0,cnt1=0,cnt2=0,temp=0;//计数用的变量必须归零
  15. memset(jishu,0,sizeof(jishu));
  16. for(int j=1;j<=n;j++)
  17. {
  18. if(mp[j][white[j]]==1)//检测该位置是否能放皇后
  19. {
  20. cnt++;
  21. }
  22. for(int k=0;k<=n-1;k++)//*解释2* *解释3*
  23. {
  24. if(j+white[j]==n+1+k) jishu[k]++;//0ton-1
  25. }
  26. for(int k=1;k<=n-1;k++)
  27. {
  28. if(j+white[j]==n+1-k) jishu[n+k-1]++;//nto2n-2
  29. }
  30. for(int k=0;k<=n-1;k++)
  31. {
  32. if(white[j]==j+k) jishu[2*n-1+k]++;//2n-1to3n-1
  33. }
  34. for(int k=1;k<=n-1;k++)
  35. {
  36. if(white[j]==j-k) jishu[3*n+k-2]++;//3nto4n-1
  37. }
  38. }
  39. /*for(int j=1;j<=50;j++)//测试用
  40. {
  41. cout<<jishu[j]<<' ';
  42. }
  43. cout<<endl;*/
  44. for(int k=0;k<=29;k++)
  45. {
  46. if(jishu[k]>=2) cnt--;
  47. }
  48. if(cnt==n)
  49. {
  50. /*for(int j=1;j<=n;j++)
  51. {
  52. cout<<"bai"<<white[j]<<' ';
  53. }
  54. cout<<endl;*/
  55. ans++;
  56. }
  57. return;
  58. }
  59. for(int i=1;i<=n;i++)//dfs全排列*解释4*
  60. {
  61. if(!viswhite[i])
  62. {
  63. viswhite[i]=true;
  64. white[p]=i;
  65. dfswhite(p+1);
  66. viswhite[i]=false;
  67. }
  68. }
  69. return;
  70. }
  71. void dfsblack(int s)//先放
  72. {
  73. if(s==n+1)
  74. {
  75. cnt=0,cnt1=0,cnt2=0,temp=0;
  76. memset(jishu,0,sizeof(jishu));
  77. for(int i=1;i<=n;i++)
  78. {
  79. if(mp[i][black[i]]==1)
  80. {
  81. cnt++;
  82. }
  83. for(int k=0;k<=n-1;k++)
  84. {
  85. if(i+black[i]==n+1+k) jishu[k]++;
  86. }
  87. for(int k=1;k<=n-1;k++)
  88. {
  89. if(i+black[i]==n+1-k) jishu[n+k-1]++;
  90. }
  91. for(int k=0;k<=n-1;k++)
  92. {
  93. if(black[i]==i+k) jishu[2*n-1+k]++;
  94. }
  95. for(int k=1;k<=n-1;k++)
  96. {
  97. if(black[i]==i-k) jishu[3*n+k-2]++;
  98. }
  99. }
  100. /*for(int j=1;j<=50;j++)
  101. {
  102. cout<<jishu[j]<<' ';
  103. }
  104. cout<<endl;*/
  105. for(int k=0;k<=29;k++)
  106. {
  107. if(jishu[k]>=2) cnt--;
  108. }
  109. if(cnt==n)
  110. {
  111. /*for(int i=1;i<=n;i++)
  112. {
  113. cout<<"hei"<<black[i]<<' ';
  114. }
  115. cout<<endl;*/
  116. for(int i=1;i<=n;i++)
  117. {
  118. mp[i][black[i]]=0;
  119. }
  120. //cout<<"开始"<<endl;
  121. dfswhite(1);
  122. //cout<<"结束"<<endl;
  123. for(int i=1;i<=n;i++)
  124. {
  125. mp[i][black[i]]=1;
  126. }
  127. }
  128. return;
  129. }
  130. for(int i=1;i<=n;i++)
  131. {
  132. if(!visblack[i])
  133. {
  134. visblack[i]=true;
  135. black[s]=i;
  136. dfsblack(s+1);
  137. visblack[i]=false;
  138. }
  139. }
  140. return;
  141. }
  142. int main()
  143. {
  144. cin>>n;
  145. for(int i=1;i<=n;i++)
  146. {
  147. for(int j=1;j<=n;j++)
  148. {
  149. cin>>mp[i][j];
  150. }
  151. }
  152. dfsblack(1);
  153. cout<<ans;
  154. return 0;
  155. }

4  车的放置

特点:在n皇后问题上进行修改,不限制放置数量,需要搜索次数更多

原题:

车的放置(蓝桥杯算法训练C/C++)_菜只因C的博客-CSDN博客车的放置(蓝桥杯算法训练C/C++)https://blog.csdn.net/m0_71934846/article/details/128876478?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22128876478%22%2C%22source%22%3A%22m0_71934846%22%7D代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int N;
  4. long long ans=0;
  5. bool vis[10];
  6. void dfs(int s)
  7. {
  8. if(s>N)
  9. {
  10. ans++;
  11. return ;
  12. }
  13. for(int i=1;i<=N;i++)
  14. {
  15. if(!vis[i])
  16. {
  17. vis[i]=true;
  18. dfs(s+1);
  19. vis[i]=false;
  20. }
  21. }
  22. dfs(s+1); //不一定从第s行开始放(即第s行没有也可以),从s+1行开始放也可以
  23. }
  24. int main()
  25. {
  26. cin>>N;
  27. dfs(1);
  28. cout<<ans;
  29. return 0;
  30. }

5  粘木棍

特点:把n个数据放入m个位置中加和(其中n>m)

原题:

粘木棍(蓝桥杯算法训练C/C++)_菜只因C的博客-CSDN博客粘木棍(蓝桥杯算法训练C/C++)https://blog.csdn.net/m0_71934846/article/details/128876620?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22128876620%22%2C%22source%22%3A%22m0_71934846%22%7D代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int a[10];
  4. int n,m;
  5. int ans=INT_MAX;
  6. bool vis[10];
  7. int sum[10];
  8. void dfs(int k)
  9. {
  10. if(k>=n+1)
  11. {
  12. int maxsum=0,minsum=INT_MAX;
  13. for(int i=1;i<=m;i++)
  14. {
  15. maxsum=max(maxsum,sum[i]);
  16. minsum=min(minsum,sum[i]);
  17. }
  18. ans=min(maxsum-minsum,ans);
  19. return ;
  20. }
  21. for(int i=k;i<=n;i++) //注意这个地方是从k开始的,防止重复计算,剪枝,否则得90分
  22. {
  23. if(!vis[i])
  24. {
  25. vis[i]=true;
  26. for(int j=1;j<=m;j++)
  27. {
  28. sum[j]+=a[i];
  29. dfs(k+1);
  30. sum[j]-=a[i];
  31. }
  32. vis[i]=false;
  33. }
  34. }
  35. }
  36. int main()
  37. {
  38. cin>>n>>m;
  39. for(int i=1;i<=n;i++)
  40. {
  41. cin>>a[i];
  42. }
  43. dfs(1);
  44. cout<<ans;
  45. return 0;
  46. }

6  24点

特点:需要两个数两个数搜索

原题:

https://blog.csdn.net/m0_71934846/article/details/128878572https://blog.csdn.net/m0_71934846/article/details/128878572代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n;
  4. int nums[4];
  5. int ans;
  6. void f(int nums[], int n)
  7. {
  8. if(n==1)//边界
  9. {
  10. if(nums[n-1]<=24)
  11. {
  12. ans=max(ans,nums[n-1]);
  13. }
  14. return ;
  15. }
  16. //遍历两个数的组合
  17. for(int i=0; i<n-1; i++)
  18. {
  19. for(int j=i+1; j<n; j++)
  20. {
  21. int a=nums[i], b=nums[j];
  22. nums[j] = a + b;//不断计算当前值放给nums[j]
  23. nums[i] = nums[n-1];//不断把未计算的值放给nums[i]
  24. f(nums, n-1);
  25. nums[j] = a * b;
  26. nums[i] = nums[n-1];
  27. f(nums, n-1);
  28. nums[j] = a - b;
  29. nums[i] = nums[n-1];
  30. f(nums, n-1);
  31. nums[j] = b - a;
  32. nums[i] = nums[n-1];
  33. f(nums, n-1);
  34. if(b!=0 && a%b==0)
  35. {
  36. nums[j] = a / b;
  37. nums[i] = nums[n-1];
  38. f(nums, n-1);
  39. }
  40. if(a!=0 && b%a==0)
  41. {
  42. nums[j] = b / a;
  43. nums[i] = nums[n-1];
  44. f(nums, n-1);
  45. }
  46. nums[i] = a;//回溯
  47. nums[j] = b;
  48. }
  49. }
  50. }
  51. int main()
  52. {
  53. cin>>n;
  54. for(int i=0; i<n; i++)
  55. {
  56. for(int j=0; j<4; j++)
  57. {
  58. cin >> nums[j];
  59. }
  60. ans = 0;
  61. f(nums, 4);
  62. cout<<ans<<endl;
  63. }
  64. return 0;
  65. }

7  五星填数

特点:全排列+筛选

原题:https://blog.csdn.net/m0_71934846/article/details/129336863?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22129336863%22%2C%22source%22%3A%22m0_71934846%22%7Dicon-default.png?t=N176https://blog.csdn.net/m0_71934846/article/details/129336863?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22129336863%22%2C%22source%22%3A%22m0_71934846%22%7D代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int a[10]={1,2,3,4,5,6,8,9,10,12};
  4. int b[10];
  5. bool vis[10];
  6. int ans;
  7. void dfs(int s,int step)
  8. {
  9. if(s==step)
  10. {
  11. /*for(int i=0;i<step;i++)
  12. {
  13. printf("%d ",b[i]);
  14. }
  15. printf("\n");*/
  16. int t=b[0]+b[2]+b[5]+b[8];
  17. if(t==b[0]+b[3]+b[6]+b[9]&&t==b[1]+b[2]+b[3]+b[4]&&t==b[1]+b[5]+b[7]+b[9]&&t==b[4]+b[6]+b[7]+b[8]) ans++;
  18. }
  19. for(int i=0;i<10;i++)
  20. {
  21. if(!vis[i])
  22. {
  23. vis[i]=true;
  24. b[s]=a[i];
  25. dfs(s+1,step);
  26. vis[i]=false;
  27. }
  28. }
  29. }
  30. int main()
  31. {
  32. dfs(0,10);
  33. printf("%d",ans/10);
  34. return 0;
  35. }

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

闽ICP备14008679号