• 队列之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));
        }
    }

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

  • 相关阅读:
    「JOI 2015 Final」城墙
    「JOI 2015 Final」舞会
    「JOISC 2014 Day1」 历史研究
    「JOISC 2015 Day 1」卡片占卜
    「NOI十联测」奥义商店
    「NOI十联测」黑暗
    「THUSCH 2017」大魔法师
    「ZJOI2014」星系调查
    HDU
    HDU
  • 原文地址:https://www.cnblogs.com/zcsor/p/6347746.html
Copyright © 2020-2023  润新知