yzoi2223集合构造的详细解法

Description - 问题描述

集合M的定义如下:

  • 1是M中的元素
  • 如果x是M中的元素,那么2x+1和4x+5都是M中的元素

那么,集合M中,最小的n个数是哪些?

Input - 输入数据

一个整数n(1<=n<=100 000)

Output - 输出数据

n个从小到大的整数,空格分隔。

 

  仔细一分析便可推知最后需要输出的数一定是单调递增的。在当时做这题的时候,旁边的gxy同学直接从1开始暴力枚举所有的奇数(2x+1和4x+5肯定是一个奇数),然后判断和前面的数是否构成2x+1或4x+5的关系,是的话就输出,否则便continue,这样的话算法复杂度就达到了O(n^2),最后还是有一个点无法通过。那么,是否还有更好的方法呢?

  事实上,由前面的单调递增可以知道:假如我们用一个数组来保存输出的数,那么这个数组肯定是2x+1产生的数再并上4x+5产生的数。这样一来也就明了了只要我们定义一个a队列来保存2x+1产生的数,用一个b队列保存4x+5产生的数。每次将a的队头与b的队头进行比较,则会出现3种情况:(A)a队头>b队头  (B)a队头=b队头  (C)a队头<b队头  这时只需要将较小者送人x来执行下一次的2x+1和4x+5,同时也不要忘记将x输出。在经过多方的查证后,我才得以知道这是使用了单调队列的思想,下面给出百度里给它的定义以有助于大家的理解:单调队列,即单调的队列。使用频率不高,但在有些程序中会有非同寻常的作用。(大概就是诸如这类的题目吧)

举例

不妨用一个问题来说明单调队列的作用和操作:
不断地向缓存数组里读入元素,也不时地去掉最老的元素,不定期的询问当前缓存数组里的最小的元素。
最直接的方法:普通队列实现缓存数组。
进队出队都是O(1),一次查询需要遍历当前队列的所有元素,故O(n)。
  好了,接下来给出代码,仅供参考:
 1 #include<iostream>
 2 using namespace std;
 3 const int maxn=1000000+10;
 4 int a[maxn],b[maxn];
 5 int x=1,n,total=1;
 6 int front1=1,front2=1,tail1=0,tail2=0;
 7 int main()
 8 {
 9     cin>>n;
10     while(total<=n)
11     {
12         if(total==n)
13         cout<<x;
14         else
15         cout<<x<<' ';
16         
17         tail1++;
18         a[tail1]=2*x+1;
19         
20         tail2++;
21         b[tail2]=4*x+5;
22         
23         if(a[front1]>b[front2])
24         {
25             x=b[front2];
26             front2++;
27             
28         }
29         else
30         {
31             if(a[front2]<b[front2])
32             {
33             x=a[front1];
34             front1++;
35             }
36             else
37             {
38                 x=a[front1];
39                 front1++;
40                 front2++;
41             }
42         }
43         total++;
44     }
45     return 0;
46 }

最后,欢迎大家的指教。

转载于:https://www.cnblogs.com/luowenqing/p/4161933.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值