当前位置:   article > 正文

算法 —— 暴力枚举

算法 —— 暴力枚举

目录

循环枚举

P2241 统计方形(数据加强版)

P2089 烤鸡

P1618 三连击(升级版)

子集枚举

P1036 [NOIP2002 普及组] 选数

P1157 组合的输出

排列枚举 

P1706 全排列问题

P1088 [NOIP2004 普及组] 火星人


循环枚举

顾名思义,通过for循环或者while循环枚举所有可能方案。 

P2241 统计方形(数据加强版)

很显然这是一道找规律的题目:正方形和长方形的唯一区别在于长宽是否相等,根据此条件可以统计矩形个数,先研究规律:

  1. for (int i = 1; i <= m; i++)
  2. for (int j = 1; j <= n; j++)

首先是横着的长方形,宽始终为1,长不断发生改变,可以看出长为2的时候,第一行个数为6个,总共有6 x 6个,长为3的时候,总共有6 x 5个……以上述循环条件来看可以得出一个规律:

长发生变化后的矩形总个数为m * ( n - j + 1)个。

第二看纵向宽发生改变,长重置为1,长为1,宽为2的时候,第一行个数为7个,总共有5 x 7 个,长为2,宽为2的时候 第一行个数为6个,共有5 x 6个……综上所述,可以得出普遍规律:
( m - i + 1) * ( n - j + 1)为每次发生长变化或者宽变化的矩形总个数,又因为长方形与正方形唯一区别是长宽是否相等,因此代码如下:

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int n, m; cin >> n >> m;
  6. long count1 = 0, count2 = 0;
  7. for (int i = 1; i <= m; i++)
  8. for (int j = 1; j <= n; j++)
  9. if (i == j)
  10. count1 += (m - i + 1) * (n - j + 1);
  11. else
  12. count2 += (m - i + 1) * (n - j + 1);
  13. cout << count1 << ' ' << count2 << endl;
  14. return 0;
  15. }

P2089 烤鸡

 暴力枚举,用十个循环解决此问题,注意:n如果小于10或者大于30直接输出0即可,原因是十种配料之和最小为10,最大为30。

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int n, count = 0; cin >> n;
  6. if (n < 10 || n > 30)
  7. {
  8. cout << 0 << endl;
  9. return 0;
  10. }
  11. else
  12. {
  13. for (int a = 1; a <= 3; a++)
  14. for (int b = 1; b <= 3; b++)
  15. for (int c = 1; c <= 3; c++)
  16. for (int d = 1; d <= 3; d++)
  17. for (int e = 1; e <= 3; e++)
  18. for (int f = 1; f <= 3; f++)
  19. for (int g = 1; g <= 3; g++)
  20. for (int h = 1; h <= 3; h++)
  21. for (int i = 1; i <= 3; i++)
  22. for (int j = 1; j <= 3; j++)
  23. if (a + b + c + d + e + f + g + h + i + j == n)
  24. count++;
  25. cout << count << endl;
  26. for (int a = 1; a <= 3; a++)
  27. for (int b = 1; b <= 3; b++)
  28. for (int c = 1; c <= 3; c++)
  29. for (int d = 1; d <= 3; d++)
  30. for (int e = 1; e <= 3; e++)
  31. for (int f = 1; f <= 3; f++)
  32. for (int g = 1; g <= 3; g++)
  33. for (int h = 1; h <= 3; h++)
  34. for (int i = 1; i <= 3; i++)
  35. for (int j = 1; j <= 3; j++)
  36. if (a + b + c + d + e + f + g + h + i + j == n)
  37. cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << e << ' ' << f << ' ' << g << ' ' << h << ' ' << i << ' ' << j << ' ' << endl;
  38. }
  39. return 0;
  40. }

P1618 三连击(升级版)

 本人比较喜欢用stl接口,下面附上代码,注意:输入123,456,789,输出123,456,789

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int a, b, c, t1, t2, t3; string def;
  4. int main()
  5. {
  6. cin >> a >> b >> c;
  7. for (int i = 1; i <= 1000 / c; i++) //记得从1开始 原因:123,456,789满足
  8. {
  9. t1 = i * a; t2 = i * b; t3 = i * c;
  10. string s1 = to_string(t1), s2 = to_string(t2), s3 = to_string(t3);
  11. string tmp; tmp += s1; tmp += s2; tmp += s3;
  12. sort(tmp.begin(), tmp.end()); //排序
  13. auto it = unique(tmp.begin(), tmp.end()); //去重操作
  14. tmp.resize(distance(tmp.begin(), it)); //计算两个迭代器之间的距离
  15. if (tmp.size() == 9 && tmp[0] == '1')
  16. {
  17. cout << s1 << ' ' << s2 << ' ' << s3 << endl;
  18. def = tmp;
  19. }
  20. }
  21. if(def.size()==0) //空的说明都不满足
  22. cout << "No!!!" << endl;
  23. return 0;
  24. }

子集枚举

P1036 [NOIP2002 普及组] 选数

这是一道简单的模拟题,枚举出所有可能情况,不会超过规定时间的,以下附上k<=3的代码,如果需要更大的k,继续仿照写即可。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n, k;
  4. bool is_prinum(int x)
  5. {
  6. for (int i = 2; i <= sqrt(x); i++)
  7. if (x % i == 0)
  8. return false;
  9. return true;
  10. }
  11. int main()
  12. {
  13. cin >> n >> k;
  14. vector<int> arr(n), pri;
  15. for (int i = 0; i < n; i++)
  16. cin >> arr[i];
  17. int count = 0;
  18. for (int i = 0; i < n; i++)
  19. {
  20. int tmp = arr[i];
  21. if (is_prinum(tmp) && k == 1)
  22. count++;
  23. if (k == 1)
  24. continue;
  25. for (int j = i + 1; j < n; j++)
  26. {
  27. int tmp = arr[i] + arr[j];
  28. if (is_prinum(tmp) && k == 2)
  29. count++;
  30. if (k == 2)
  31. continue;
  32. for (int z = j + 1; z < n; z++)
  33. {
  34. int tmp = arr[i] + arr[j] + arr[z];
  35. if (is_prinum(tmp) && k == 3)
  36. count++;
  37. if (k == 3)
  38. continue;
  39. }
  40. }
  41. }
  42. cout << count << endl;
  43. return 0;
  44. }

P1157 组合的输出

与上面一题类似,也是求子集,直接for循环叠加:,下面只举例到3:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n, k;
  4. int main()
  5. {
  6. cin >> n >> k;
  7. vector<string> arr(n), ans;
  8. for (int i = 0; i < n; i++)
  9. arr[i] = to_string(i + 1);
  10. for (int i = 0; i < n; i++)
  11. {
  12. if (k == 1)
  13. {
  14. cout << setw(3) << stoi(arr[i]) << endl;
  15. continue;
  16. }
  17. for (int j = i + 1; j < n; j++)
  18. {
  19. if (k == 2)
  20. {
  21. cout << setw(3) << arr[i] << setw(3) << arr[j] << endl;
  22. continue;
  23. }
  24. for (int z = j + 1; z < n; z++)
  25. {
  26. if (k == 3)
  27. {
  28. cout << setw(3) << arr[i] << setw(3) << arr[j] << setw(3) << arr[z] << endl;
  29. continue;
  30. }
  31. }
  32. }
  33. }
  34. return 0;
  35. }

排列枚举 

P1706 全排列问题

本题可以点击此链接看我另一篇文章,其中解释了如何使用stl库的函数解决该问题。


P1088 [NOIP2004 普及组] 火星人

本题不过多赘述,与上题一样也是stl的使用,以下为代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int main()
  4. {
  5. int n, m; cin >> n >> m;
  6. vector<int> arr(n);
  7. for (int i = 0; i < n; i++)
  8. cin >> arr[i];
  9. for (int j = 1; j <= m; j++)
  10. next_permutation(arr.begin(), arr.end());
  11. for (auto e : arr)
  12. cout << e << ' ';
  13. return 0;
  14. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/890294
推荐阅读
相关标签
  

闽ICP备14008679号