[服务器软件] 1-9 堆宝塔

466 0
Honkers 2026-4-8 22:29:23 来自手机 | 显示全部楼层 |阅读模式

题目要求:

堆宝塔游戏是让小朋友根据抓到的彩虹圈的直径大小,按照从大到小的顺序堆起宝塔。但彩虹圈不一定是按照直径的大小顺序抓到的。聪明宝宝采取的策略如下:

  • 首先准备两根柱子,一根 A 柱串宝塔,一根 B 柱用于临时叠放。
  • 把第 1 块彩虹圈作为第 1 座宝塔的基座,在 A 柱放好。
  • 将抓到的下一块彩虹圈 C 跟当前 A 柱宝塔最上面的彩虹圈比一下,如果比最上面的小,就直接放上去;否则把 C 跟 B 柱最上面的彩虹圈比一下:
  • 如果 B 柱是空的、或者 C 大,就在 B 柱上放好;
  • 否则把 A 柱上串好的宝塔取下来作为一件成品;然后把 B 柱上所有比 C 大的彩虹圈逐一取下放到 A 柱上,最后把 C 也放到 A 柱上。

重复此步骤,直到所有的彩虹圈都被抓完。最后 A 柱上剩下的宝塔作为一件成品,B 柱上剩下的彩虹圈被逐一取下,堆成另一座宝塔。问:宝宝一共堆出了几个宝塔?最高的宝塔有多少层?

输入格式:

输入第一行给出一个正整数 N(≤103),为彩虹圈的个数。第二行按照宝宝抓取的顺序给出 N 个不超过 100 的正整数,对应每个彩虹圈的直径。

输出格式:

在一行中输出宝宝堆出的宝塔个数,和最高的宝塔的层数。数字间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

  1. 11
  2. 10 8 9 5 12 11 4 3 1 9 15
复制代码

输出样例:

  1. 4 5
复制代码

样例解释:

宝宝堆成的宝塔顺次为:

  • 10、8、5
  • 12、11、4、3、1
  • 9
  • 15、9

解题思路:

如此长的题目,其实可以总结为以下几点:

1.初始使用A柱;

2.如果当前圆环比A柱顶部小,则可以直接放上去;

3.否则,如果B柱顶部比当前圆环小,也可以放入B柱;

4.如果两柱都无法放,则视为A柱已构成一个完整宝塔,将A柱的圆环收集后清空;

5.将B柱中比当前圆环大的元素转移到A柱,以尝试继续构建新塔;

6.最后,把剩余的A柱、B柱也分别视为塔加入统计中。

7.最后的最后,再输出宝塔总数和最高宝塔的层数。

代码:

  1. #include <iostream>
  2. #include <vector>
  3. #include <stack>
  4. #include <algorithm>
  5. using namespace std;
  6. int main()
  7. {
  8. int N;
  9. cin >> N;
  10. vector<int> rings(N);
  11. for (int i = 0; i < N; ++i)
  12. {
  13. cin >> rings[i];
  14. }
  15. vector<vector<int> > towers; // 保存每个完整宝塔(记录每层)
  16. stack<int> A, B; // A柱和B柱
  17. int max_height = 0;
  18. for (int i = 0; i < N; ++i)
  19. {
  20. int C = rings[i];
  21. if (A.empty())
  22. {
  23. A.push(C);
  24. }
  25. else if (C < A.top())
  26. {
  27. A.push(C);
  28. }
  29. else
  30. {
  31. if (B.empty() || C > B.top())
  32. {
  33. B.push(C);
  34. }
  35. else
  36. {
  37. // A柱成品宝塔完成
  38. vector<int> tower;
  39. while (!A.empty())
  40. {
  41. tower.push_back(A.top());
  42. A.pop();
  43. }
  44. max_height = max(max_height, (int)tower.size());
  45. towers.push_back(tower);
  46. // B柱比C大的移到A柱
  47. while (!B.empty() && B.top() > C)
  48. {
  49. A.push(B.top());
  50. B.pop();
  51. }
  52. A.push(C);
  53. }
  54. }
  55. }
  56. // 收尾:A柱宝塔
  57. if (!A.empty())
  58. {
  59. vector<int> tower;
  60. while (!A.empty())
  61. {
  62. tower.push_back(A.top());
  63. A.pop();
  64. }
  65. max_height = max(max_height, (int)tower.size());
  66. towers.push_back(tower);
  67. }
  68. // B柱也成一个塔
  69. if (!B.empty())
  70. {
  71. vector<int> tower;
  72. while (!B.empty())
  73. {
  74. tower.push_back(B.top());
  75. B.pop();
  76. }
  77. max_height = max(max_height, (int)tower.size());
  78. towers.push_back(tower);
  79. }
  80. cout << towers.size() << " " << max_height << endl;
  81. return 0;
  82. }
复制代码

答题结果:

个人总结:

1.数据结构:根据题目给出的信息,我们不难发现,该题目适合使用栈的结构进行解决,一共需要建立两个栈,分别模拟两个宝塔。

2.思路:对于每个个圆环来说,每个新圆环按照大小关系被有序地放置在A柱或B柱中。如果无法继续放置,则将当前A柱的内容保存为一个完成的宝塔,并清空以重新构建。

3.核心点:该题目的核心在于通过合理地在两个柱子之间转移圆环,实现尽可能多的塔构建,并记录其中最高的塔高度。最本质的算法核心则是贪心算法的思想。

4.语言:最后,再次强调对C++vector容器和stack的正确使用,二维的vector模拟了一个动态的二维数组,而stack提供的pop、top、push等方法则模拟了圆环的拿取和放下,实现了题目的要求。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2026 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行