zoukankan      html  css  js  c++  java
  • 队列之blah集合

      做了一个NOI上面的问题,叫blah集合,以a为基数,则2x+1和3x+1都在集合中,且集合中全部元素都由此计算得来。a∈[1,50],问升序排列后第n(n∈[1,1000000])个元素是多少。以输入示例a=1,n=100,b[n]=418为例:

    集合中第一个元素(基数)为1,
          1  3  4  7 10 9 2x+
    : 3     15 21 19…… 3x+: 4 10 13 22 31 27……

    依次计算时会发现每1个数据会变为2个,这些数又会发生交叉。题目需要得到升序后第n个,我们如果先计算再排序一定会超时的,所以我们需要分别把2x+1和3x+1存储起来,然后取之前存储的较小的输出出来,队列很适合这项工作:

    #include<iostream>
    #include<queue>
    typedef unsigned long long uint64;
    using namespace std;
    uint64 blah(int base,int maxid){
        int curval=base,curid=1;
        queue<uint64> x2,x3;
        x2.push(curval*2+1);
        x3.push(curval*3+1);
        while(maxid!=curid){
            if(x2.front()==x3.front()){
                curval=x2.front();
                x2.pop();
                x3.pop();
            }else if(x2.front()<x3.front()){
                curval=x2.front();
                x2.pop();
            }else{
                curval=x3.front();
                x3.pop();
            }
            x2.push(curval*2+1);
            x3.push(curval*3+1);
            curid++;
        }
        return curval;
    }
    int main(){
        int base,maxid;
        while(true){
            cin>>base>>maxid;
            cout<<blah(base,maxid)<<endl;
        }
    }

    不过遗憾的是,这份代码超时了,虽然它在我的计算机上计算得到结果是瞬间的事情。那么问题在哪呢?只能说可能出现在对front和pop的调用耗时上,当然也可能有内存分配方面的耗时。好吧,我们避免这些调用和重复的初始化——用数组来模拟一下队列:

    #include<iostream>
    typedef unsigned long long uint64;
    using namespace std;
    uint64 x2[1000000],x3[1000000];
    uint64 blah(int base,int maxid){
        int curval=base,curid=1,x2id=0,x3id=0,x2cnt=0,x3cnt=0,x2val,x3val;
        x2[x2cnt]=curval*2+1;
        x3[x3cnt]=curval*3+1;
        while(maxid!=curid){
            x2val=x2[x2id];
            x3val=x3[x3id];
            if(x2val==x3val){
                curval=x2val;
                x2id++;
                x3id++;
            }else if(x2val<x3val){
                curval=x2val;
                x2id++;
            }else{
                curval=x3val;
                x3id++;
            }
            x2[++x2cnt]=curval*2+1;
            x3[++x3cnt]=curval*3+1;
            curid++;
        }
        return curval;
    }
    int main(){
        int base,maxid;
        while(scanf("%d %d",&base,&maxid)!=EOF){
            printf("%llu
    ",blah(base,maxid));
        }
    }

    这份代码就以很短的时间通过了测试。

  • 相关阅读:
    Python处理海量手机号码
    javascript面向对象
    NET实现的DDD、CQRS与微服务架构
    增加打赏功能
    开发测试时给 Kafka 发消息的 UI 发送器――Mikasa
    Computational Network Toolkit (CNTK) 是微软出品的开源深度学习工具包
    线程同步和多线程优先级
    linux sed命令详解(转)
    linux sort,uniq,cut,wc命令详解 (转)
    linux awk命令详解(转)
  • 原文地址:https://www.cnblogs.com/zcsor/p/6347746.html
Copyright © 2011-2022 走看看