队列之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+1: 3  7  9 15 21 19……

3x+1: 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\n",blah(base,maxid));
    }
}

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

时间: 2024-08-24 13:44:04

队列之blah集合的相关文章

Java多线程 阻塞队列和并发集合

转载:大关的博客 Java多线程 阻塞队列和并发集合 本章主要探讨在多线程程序中与集合相关的内容.在多线程程序中,如果使用普通集合往往会造成数据错误,甚至造成程序崩溃.Java为多线程专门提供了特有的线程安全的集合类,通过下面的学习,您需要掌握这些集合的特点是什么,底层实现如何.在何时使用等问题. 3.1 BlockingQueue接口 java阻塞队列应用于生产者消费者模式.消息传递.并行任务执行和相关并发设计的大多数常见使用上下文. BlockingQueue在Queue接口基础上提供了额外

集合类——集合输出、栈和队列及Collections集合

1.集合输出 在之前我们利用了toString()及get()方法对集合进行了输出,其实那都不是集合的标准输出,集合输出有四种方式:Iterator.ListIterator.Enumeration.foreach. (1)Iterator(迭代输出) 在jdk1.5之前,在Collection接口中就有iterator()方法来获取Iterator接口的实例化对象,而在jdk1.5之后该方法被提升到Iterable接口中,但是不管怎么提升,只要Collection有该方法,则List和Set也

数据结构Java实现07----队列:顺序队列&amp;顺序循环队列、链式队列、顺序优先队列

数据结构Java实现07----队列:顺序队列&顺序循环队列.链式队列.顺序优先队列 一.队列的概念: 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其另一端进行删除操作. 队列中允许进行插入操作的一端称为队尾,允许进行删除操作的一端称为队头.队列的插入操作通常称作入队列,队列的删除操作通常称作出队列. 下图是一个依次向队列中插入数据元素a0,a1,...,an-

java多线程系类:JUC集合:01之框架

概要 之前,在"Java 集合系列目录(Category)"中,讲解了Java集合包中的各个类.接下来,将展开对JUC包中的集合进行学习.在学习之前,先温习一下"Java集合包".本章内容包括:Java集合包JUC中的集合类 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3498454.html Java集合包 在"Java 集合系列01之 总体框架"中,介绍java集合的架构.主体内容包括Colle

优先队列——二项队列(binominal queue)

[0]README 0.1) 本文文字描述部分转自 数据结构与算法分析, 旨在理解 优先队列——二项队列(binominal queue) 的基础知识: 0.2) 本文核心的剖析思路均为原创(insert,merge和deleteMin的操作步骤图片示例), 源代码均为原创: 0.3) for original source code, please visit https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree

C#常用集合的使用

大多数集合都在System.Collections,System.Collections.Generic两个命名空间.其中System.Collections.Generic专门用于泛型集合. 针对特定类型的集合类型位于System.Collections.Specialized;命名空间: 线程安全的集合类位于System.Collections.Concurrent;命名空间. 下面是集合和列表实现的接口如下: 一.列表 [csharp] view plaincopy [Serializab

scala编程第17章学习笔记(1)——集合类型

列表 列表的初始化及对其首尾的访问: scala> val colors = List("red", "blue", "green") colors: List[String] = List(red, blue, green) scala> colors.head res15: String = red scala> colors.tail res16: List[String] = List(blue, green) 数组 创

Java集合框架(二)day_16

16.集合框架(去除ArrayList中重复字符串元素方式)(掌握) public class Demo1_ArrayList { /** * * A:案例演示 * 需求:ArrayList去除集合中字符串的重复值(字符串的内容相同) * 思路:创建新集合方式 */ public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("a"); list.add("a"

10、特殊集合

特殊集合 1.栈 stack 在栈集合中,元素只能一个一个往里进,而且遵循“先进后出”的规则,即最先进的最后出.在栈中没有索引. //清空 a.Clear(); //判断是否存在某元素 a.Contains(5); //定义栈 Stack b=new Stack(); //清空 b.Clear(); //判断是否存在某元素 b.Contains(5); //获取最后一个进入栈的元素的值 b.Peek(); //读取并移除最后一个元素的值 b.Pop(); //将元素一个个推入集合,即添加元素 b