• 王道机试C++第 5 章 数据结构二:队列queue和21年蓝桥杯省赛选择题Day32


    目录

    5.2 队列

    1.STL-queue

    课上演示:

    基本代码展示:

    2. 队列的应用

    例:约瑟夫问题 No. 2

    题目描述:

    思路提示:

    代码展示:

    例:猫狗收容所

    题目描述:

    代码表示:

    蓝桥杯21年填空题

    试题 A :空间

    【问题描述】

    【答案提交】

    试题 B :卡片

    【问题描述】

    【答案提交】

    试题 C :直线

    【问题描述】

    【答案提交】

    试题 D :货物摆放

    【问题描述】

    【答案提交】


    5.2 队列

    队列( Queue )是一种线性的序列结构,其存放的元素按照线性的逻辑次序排列,但与一般的线性序列结构如数组或向量相比,队列的操作只限于逻辑上的两端,即新元素只能从队列
    一端插入,并且只能从另一端删除已有的元素。
    允许队列插入的一端称为队列的尾部,允许队列删除的一端称为队列的头部。因此,对于元素说,插入与删除就分别称为入队和出队。
    遵守所谓的先进先出 First-In First-Out, FIFO )规则,即越早入队的元素将会越早出队,而越晚入队的元素将会越晚出队。

    1STL-queue

    在正式介绍队列的应用之前,先介绍标准库中的队列模板。对于队列模板,读者不必过多
    地关注其实现细节,掌握其在程序中的用法即可。
    1 queue 的定义
    要使用 queue 标准模板,就应在代码中添加头文件,其格式为 #include 。定义一个队列 queue 的写法是 queue name ,其中 typename 是队列元素的类型,它可以是任意数据类型,name 是所定义队列的名字。
    2 queue 的状态
    queue 中常用作判断的状态有两个:一个是返回当前队列是否为空的 empty() ,另一个是返回当前队列元素个数的 size()
    3 queue 元素的添加或删除
    定义一个队列后,如果要向其中添加新的元素push()删除已有的元素 pop()
    4 queue 元素的访问
    只能对队列的头尾两端进行操作,获得头front()  尾back()。
    课上演示:
    基本代码展示:
    1. #include <bits/stdc++.h>
    2. using namespace std;
    3. int main() {
    4. queue<int> myQueue; // 定义并初始化一个整型队列
    5. // 输出队列初始大小
    6. printf("the size of myQueue: %zu\n", myQueue.size());
    7. for (int i = 0; i < 10; ++i) {
    8. myQueue.push(i); // 将元素推入队列
    9. }
    10. // 输出队列的前端和后端元素
    11. printf("the front of myQueue: %d\n", myQueue.front());
    12. printf("the back of myQueue: %d\n", myQueue.back());
    13. // 输出队列当前大小
    14. printf("the size of myQueue: %zu\n", myQueue.size());
    15. int sum = 0;
    16. while (!myQueue.empty()) {
    17. sum += myQueue.front(); // 累加队列前端元素
    18. myQueue.pop(); // 弹出队列前端元素
    19. }
    20. // 输出累加和
    21. printf("sum: %d\n", sum);
    22. //再次检查是否为空
    23. if (myQueue.empty()) {
    24. printf("myQueue is empty\n");
    25. }
    26. // 输出队列最终大小(应该是0
    27. printf("the size of myQueue: %zu\n", myQueue.size());
    28. return 0;
    29. }

    2. 队列的应用

    例:约瑟夫问题 No. 2
    题目描述:
    n 个小孩围坐成一圈,并按顺时针编号为 1, 2,... , n ,从编号为 p 的小孩顺时针依次报数,由 1
    m ,报到 m 时,这名小孩从圈中出去;然后下一名小孩再从 1 报数,报到 m 时再出去。以此
    类推,直到所有小孩都从圈中出去。请按出去的先后顺序输出小孩的编号。
    输入: 第一个是 n ,第二个是 p ,第三个是 m 0 < m , n < 300 )。
               最后一行是:0 0 0
    输出: 按出圈的顺序输出编号,编号之间以逗号间隔。
    样例输入:
    8 3 4
    0 0 0
    样例输出:
    6,2,7,4,3,5,1,8
    思路提示:

    代码展示:
    1. #include <bits/stdc++.h>
    2. using namespace std;
    3. int main() {
    4. int n,p,m;
    5. while(true){
    6. scanf("%d%d%d",&n,&p,&m);
    7. if(n==0&&p==0&&m==0){
    8. break;
    9. }
    10. //1、排队
    11. //队列中的元素是孩子的编号
    12. queue<int>children;
    13. //把第一轮要喊编号的孩子排好队
    14. //i遍历孩子的编号,j记录已经遍历的孩子数量
    15. for(int i=p,j=0;j<n;++j){
    16. children.push(i);
    17. ++i;//p ->p+1 ->p+2 ->..n ->1 ->...->p-1
    18. if(i>n){
    19. i=1;
    20. }
    21. }
    22. }
    23. //2、喊号过程
    24. int num=1;//将要喊的号
    25. while(true){
    26. int cur=children.front();//cur是队首孩子的编号
    27. children.pop();
    28. if(num==m){//检查刚才喊得号是不是1
    29. num=1;//下一个就是1
    30. //喊号的同学不需要归队
    31. if(children.empty()){
    32. printf("%d\n",cur);
    33. break;
    34. }else{
    35. //还有同学在喊号
    36. printf("%d",cur);
    37. }
    38. }
    39. } else{
    40. //喊得号码不是m,归队
    41. num=num+1;
    42. children.push(cur);
    43. }
    44. return 0;
    45. }

    例:猫狗收容所
    题目描述:
    有家动物收容所只收留猫和狗,但有特殊的收养规则。收养人有两种收养方式:
    第一种为直接收养所有动物中最早进入收容所的。
    第二种为选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的。给定一个操作序列代表所有事件。
    若第一个元素为 1 ,则代表有动物进入收容所。第二个元素为动物的编号,正数代表狗,负数代表猫。
    若第一个元素为 2 ,则代表有人收养动物。第二个元素若为 0 ,则采取第一种收养方式;若为 1, 则指定收养狗;若为-1 ,则指定收养猫。请按顺序输出收养动物的序列。
    若出现不合法的操作,即没有可以符合领养要求的动物,则将这次领养操作忽略。
    输入: 第一个是 n ,它代表操作序列的次数。接下来是 n 行,每行有两个值 m t ,分别代表题目中操作的两个元素。
    输出:按顺序输出收养动物的序列,编号之间以空格间隔。
    样例输入:
    6
    1 1
    1 -1
    2 0
    1 2
    2 -1
    2 1
    样例输出:
    1 -1 2
    代码表示:
    1. #include <bits/stdc++.h>
    2. using namespace std;
    3. // 定义动物结构体
    4. struct animal {
    5. int num; // 动物编号
    6. int seq; // 次序标志
    7. animal(int n, int o) : number(n), order(o) {} // 构造函数
    8. };
    9. int main() {
    10. queue<animal> catque; // 猫的队列
    11. queue<animal> dogque; // 狗的队列
    12. int n;
    13. int seq = 0;
    14. scanf("%d",&n); // 输入动物数量
    15. for (int i = 0; i < n; ++i) {
    16. int method, pare;
    17. scanf("%d%d",&method,&pare)// 输入操作方法和动物类型
    18. if (method == 1) {
    19. // 入队操作
    20. if (pare > 0)
    21. {
    22. //操作狗
    23. animal dog;
    24. dog.num=para;
    25. dog.seq=seq;
    26. ++seq;
    27. dogque.push(dog);
    28. } else
    29. {
    30. animal cat;
    31. cat.num=para;
    32. cat.seq=seq;
    33. ++seq;
    34. catque.push(dog);
    35. }
    36. }
    37. else
    38. {
    39. // 出队操作
    40. if (pare == 0 && !dogque.empty() && !catque.empty()) {
    41. // 猫和狗都不为空,比较次序出队
    42. if (dogque.front().pare < catque.front().pare) {
    43. cout << dogque.front().number << " ";
    44. dogque.pop();
    45. } else {
    46. cout << catque.front().number << " ";
    47. catque.pop();
    48. }
    49. } else if (pare == 0 && dogque.empty() && !catque.empty()) {
    50. // 狗为空,只有猫,出队猫
    51. cout << catque.front().num << " ";
    52. cats.pop();
    53. } else if (pare== 0 && !dogque.empty() && catque.empty()) {
    54. // 猫为空,只有狗,出队狗
    55. cout << dogque.front().num << " ";
    56. dogs.pop();
    57. } else if (pare == 1 && !dogque.empty()) {
    58. // 只出队狗
    59. cout << dogque.front().num<< " ";
    60. dogs.pop();
    61. } else if (pare== -1 && !catque.empty()) {
    62. // 只出队猫
    63. cout << catque.front().num<< " ";
    64. catque.pop();
    65. }
    66. }
    67. }
    68. cout << endl; // 输出换行符
    69. return 0;
    70. }

    蓝桥杯21年填空题

    试题 A :空间

    【问题描述】

    小蓝准备用256MB 的内存空间开一个数组,数组的每个元素都是 32 位二进制整数,如果不考虑程序占用的空间和维护内存需要的辅助空间,请问256MB 的空间可以存储多少个32 位二进制整数?

    【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

    答:相当于一道计组的题2^28/2^2,再用pow(2,26);

    6.71089e+007


    试题 B :卡片

    【问题描述】

    小蓝有很多数字卡片,每张卡片上都是数字 0 到 9 。

    小蓝准备用这些卡片来拼一些数,他想从1开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。小蓝想知道自己能从 1 拼到多少。

    例如,当小蓝有 30张卡片,其中 0 到 9 各 3 张,则小蓝可以拼出 1 到 10 ,但是拼 11 时卡片 1 已经只有一张了,不够拼出 11 。

    现在小蓝手里有 0 到 9 的卡片各 2021 张,共20210 张,请问小蓝可以从 1 拼到多少?

    提示:建议使用计算机编程解决问题。

    【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

    3181(短代码+word不容易呀,菜就得练┭┮﹏┭┮)

    代码:

    1. #include <bits/stdc++.h>
    2. using namespace std;
    3. int card[10];
    4. bool check(int num)
    5. {
    6. while (num)
    7. {
    8. int a = num % 10;
    9. if (a == 1)
    10. if (card[1] == 0)
    11. return false;
    12. else
    13. card[1]--;
    14. num = num / 10;
    15. }
    16. return true;
    17. }
    18. int main()
    19. {
    20. for (int i = 0; i <= 9; i++)
    21. {
    22. card[i] = 2021;
    23. }
    24. for (int i = 1;check(i); i++)
    25. {
    26. cout << i << endl;
    27. }
    28. return 0;
    29. }

    试题 C :直线

    【问题描述】

    【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

    目前还不会!!之后搞懂!


    试题 D :货物摆放

    【问题描述】

    【答案提交】

    这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

    代码部分

    1. #include <bits/stdc++.h>
    2. using namespace std;
    3. int main()
    4. {
    5. long long num=2021041820210418;
    6. vector<long long> divisor;
    7. for(long long i=1;i<=sqrt(num);i++){
    8. if(num%i==0){
    9. divisor.push_back(i);
    10. long long j=num/i;
    11. //避免将重复的因子添加到divisor向量中
    12. if(j!=i){
    13. divisor.push_back(j);//如果是因子就将因子压入因子容器里
    14. }
    15. }
    16. }
    17. int count=0;//设置好题解是count初值为0
    18. //设置三个迭代器遍历因子容器找三个因子相乘就是num的组合,答案就在这些组合里面
    19. vector<long long>::iterator a,b,c;
    20. for(a=divisor.begin();a!=divisor.end();a++){
    21. for(b=divisor.begin();b!=divisor.end();b++){
    22. for(c=divisor.begin();c!=divisor.end();c++){
    23. if((*a)*(*b)*(*c)==num){
    24. count++;
    25. }
    26. }
    27. }
    28. }
    29. cout<<count<<endl;
    30. return 0;
    31. }

    心得体会:

    int main()
    {
       long long num=2021041820210418;
       vector divisor;
       for(long long i=1;i<=sqrt(num);i++){
         if(num%i==0){
           divisor.push_back(i);
           long long j=num/i;
           if(j!=i){
             divisor.push_back(j);//如果是因子就将因子压入因子容器里
           }
         }
       }

    对于这段代码是用于计算给定的数num的因子。

    首先,使用一个for循环来遍历从1到num的平方根之间的整数,即i * i <= num。这是因为一个数的因子不会超过它的平方根。

    在循环中,通过判断num是否能被i整除来确定i是否是num的因子。如果num能被i整除,即num % i == 0,则将i添加到因子容器divisor中。

    接下来,使用变量j存储num除以i的结果,即j = num / i。然后,通过判断j是否等于i,来避免将重复的因子添加到divisor中。如果j不等于i,则将j也添加到divisor中。

    经过循环遍历后,divisor中存储了num的所有因子,这段代码的目的是为了生成一个包含num所有因子的容器divisor,以便后续的处理和计算。

  • 相关阅读:
    资深架构师必备知识:Netty+MySQL+并发+JVM+多线程
    单调栈的常见用法
    数据结构与算法_BST树_BST树的定义及删除操作
    HDLBits: 在线学习 SystemVerilog(六)-Problem 24-27
    [Unity] GPU动画实现(二)——网格合并
    list链表
    2022-回归日-蔚来已来秋招笔试
    一文让你了解数据采集
    CentOS 7 安装新版本的Git
    常见的linux命令
  • 原文地址:https://blog.csdn.net/weixin_63597914/article/details/136606915