zoukankan      html  css  js  c++  java
  • wikioi 1245最小的N个和

    2013-09-08 10:12

    LRJ的算法竞赛入门经典训练指南里有类似的题,原题要难很多,p189页

    读入A,B两组中的所有数后,建立N个有序表:

    A1+B1<A2+B1<A3+B1<...<AN+B1

    A1+B2<A2+B2<A3+B2<...<AN+B2

    ...

    A1+BN<A2+BN<A3+BN<...<AN+AN

    将每个有序表的第一个数字(记作s)连同A,B的下标0推入优先队列,这样我们每一次取出队列中的队首,显然这个元素的s是最小的,输出。与此同时,我们需要延续这个有序表。在取出的结构体中,令其标号a加1,b的标号不变,那么,s=B[b]+A[a]。

    实际操作时,因为b的标号不变,就可以不保存下标b以及数组B,直接将读入数组B改为读入每一个元素(记为k),并将s=k+a[1],a=1推入队列,每次取出元素后,令其a=a+1,s=s+A[a]-A[a-1],如此减少空间占用,只需要一个队列和一个保存A的数组

    //By BLADEVIL
    type
        aa=record
        num                 :array[0..100010] of longint;
    end;
        bb=record
        num,size            :longint;
     
    end;
     
    var
        x, y                :aa;
        n                   :longint;
        heap                :array[0..300010] of bb;
        t                   :longint;
     
     
    procedure swap(var a,b:longint);
    var
        z                   :longint;
    begin
        z:=a; a:=b; b:=z;
    end;
     
    procedure qs(var xx:aa; low,high:longint);
    var
        i, j, z,  c         :longint;
    begin
        i:=low; j:=high; c:=xx.num[(i+j) div 2];
        while i<j do
        begin
            while c<xx.num[j] do dec(j);
            while c>xx.num[i] do inc(i);
            if i<=j then
            begin
                swap(xx.num[i],xx.num[j]);
                inc(i); dec(j);
            end;
        end;
        if i<high then qs(xx,i,high);
        if j>low then qs(xx,low,j);
    end;
     
    procedure init;
    var
        i                   :longint;
    begin
        read(n);
        for i:=1 to n do read(x.num[i]);
        for i:=1 to n do read(y.num[i]);
        qs(x,1,n);
        qs(y,1,n);
    end;
     
    procedure up(x:longint);
    begin
        while (x>1) and (heap[x].num<heap[x div 2].num) do
        begin
            swap(heap[x].num,heap[x div 2].num);
            swap(heap[x].size,heap[x div 2].size);
            x:=x div 2;
        end;
    end;
     
    procedure down(x:longint);
    var
        k                   :longint;
    begin
        k:=x;
        while true do
        begin
            if (x<<1<=t) and (heap[k].num>heap[x<<1].num) then k:=x<<1;
            if (x<<1+1<=t) and (heap[k].num>heap[x<<1+1].num) then k:=x<<1+1;
            if k=x then exit;
            swap(heap[x].num,heap[k].num);
            swap(heap[x].size,heap[k].size);
            x:=k;
        end;
    end;
     
    procedure main;
    var
        i                   :longint;
    begin
        t:=0;
        for i:=1 to n do
        begin
            inc(t);
            heap[t].num:=x.num[i]+y.num[1];
            heap[t].size:=1;
            up(t);
        end;
        for i:=1 to n do
        begin
            write(heap[1].num,' ');
            inc(t);
            heap[t].num:=heap[1].num-y.num[heap[1].size]+y.num[heap[1].size+1];
            heap[t].size:=heap[1].size+1;
            up(t);
            heap[1].num:=heap[t].num;
            heap[1].size:=heap[t].size;
            dec(t);
            down(1);
     
        end;
        writeln;
    end;
     
    begin
        init;
        main;
    end.
  • 相关阅读:
    逝者如斯夫(一)
    C#面向对象-多态
    C#基础知识1-深入理解值类型和引用类型
    一个简单的C#爬虫程序
    C# Web分页功能实现
    Web前端JS实现轮播图原理
    visual studio2019 离线MSDN文档安装
    C#中类的修饰符
    HALCON数据类型和C#对应数据类型的对比
    关于HACLON程序导出C#程序,运行报错解决方法
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3433486.html
Copyright © 2011-2022 走看看