zoukankan      html  css  js  c++  java
  • luogu P2343 宝石管理系统 暴力,思维,二分

    P2343 宝石管理系统

    题目描述

    GY君购买了一批宝石放进了仓库。有一天GY君心血来潮,想要清点他的宝石,于是把m个宝石都取出来放进了宝石管理系统。每个宝石i都有一个珍贵值vi,他希望你能编写程序查找到从大到小第n珍贵的宝石。但是现在问题来了,他非常不小心的留了一些宝石在仓库里面,有可能要往现有的系统中添加宝石。这些宝石的个数比较少。他表示非常抱歉,但是还是希望你的系统能起作用。

    输入输出格式

    输入格式:

    第一行一个整数m,q,表示已经取出来的宝石个数以及接下来的查询或插入操作个数。

    第二行m个整数,表示这m个宝石的珍贵值。

    以下q行,每行两个整数c,n,

    若c=1(即询问),则输出当前第n珍贵的宝石,

    若c=2(即插入),则往系统中插入珍贵值为n的宝石。

    输出格式:

    对于每个c=1(询问),输出当前第n珍贵的宝石的珍贵值vi。

    输入输出样例

    输入样例#1:
    5 3
    1 3 2 5 6
    1 3
    2 4
    1 6
    
    输出样例#1:
    3
    1

    Pre

    好把,这题其实是zyf小盆友叫我去做的,一开始想用数组next模拟链表,结果打了个错误百出的版本交了上去,然后就WA+TLE了然后猛然意识到这题直接模拟链表的时复超高

    所以开始想用树状数组来记录,然后就怂了,开始寻找其他方法……

    暴力qsort一遍,然后每次加入后再qsort = 60 points  

    for一遍尝试找第一比他小的,可以直接插入到它前面 ,然后平移数组= 80 points

    Solution

    // 注意:感觉这似乎不是正解qwq

    于是进入正题

    首先既然我们可以直接插入加平移数组,既然可以往左平移,为啥不能往右呢?

    所以我们可以在平移时加个优化判断向左平移方便还是向右平移方便

    ------------ubuntu上的gdb坏了,于是只能用write来debug .... 【欲哭无泪】

    好,处理完后啦,还是80 points ?

    于是机智的你想到了二分

    没错再加上二分找第一比他小的 就AC啦
     
    原来这么水。。。
     
    最后分析一下时间复杂度,忽略二分时间复杂度添加操作总的大概为$O(q ( log^n_2+ lfloor n/2 floor ))|q leq 10000,n leq 110000$,查询就是$O(q)$
     
     1 program wonder;
     2 var
     3   n,q,i,c,x,left,right,aa,bb:longint;
     4   a:array[-110000..110000] of longint;
     5 
     6 procedure qsort(l,r:longint);  //从大到小qsort
     7 var i,j,m,x:longint;
     8 begin
     9     i:=l;  j:=r;  m:=a[(l+r) div 2];
    10     repeat
    11     while a[i]>m do inc(i);
    12     while a[j]<m do dec(j);
    13     if i<=j then begin
    14                   x:=a[i];a[i]:=a[j];a[j]:=x;
    15                   inc(i);dec(j);
    16                 end;
    17     until i>j;
    18     if i<r then qsort(i,r);
    19     if j>l then qsort(l,j);
    20 end;
    21 
    22 procedure add;
    23 var
    24    ii,jj,m:longint;
    25 begin
    26    
    27   ii:=left;  jj:=right;
    28   while ii<jj do
    29     begin
    30       m:=ii+(jj-ii) div 2;
    31       if a[m]>x then ii:=m+1
    32         else jj:=m-1;
    33     end;                    //二分查找第一个比他小的
    34 
    35   for ii:=ii to right do    //insert
    36    if x>a[ii] then
    37     begin
    38       bb:=n-ii+1;          //bb为右移数组的花费
    39       aa:=n-bb;            //aa为左移数组的花费
    40       inc(n);              //n为元素个数                          
    41       if bb<aa then begin
    42                       inc(right); 
    43                       for jj:= right downto ii+1 do a[jj]:=a[jj-1];
    44                       a[ii]:=x;
    45                     end
    46       else  begin
    47                dec(left);
    48                for jj:= left to ii-2 do a[jj]:=a[jj+1];
    49                a[ii-1]:=x;
    50              end;
    51        break;
    52     end;
    53 end;
    54 
    55 begin
    56   readln(n,q);
    57   for i:= 1 to n do
    58     read(a[i]);
    59 
    60   qsort(1,n);
    61 
    62   left:=1;  right:=n;
    63   for i:= 1 to q do
    64   begin
    65    readln(c,x);
    66     if c=1 then writeln(a[left+x-1])  
    67       else add;              
    68   end;
    69 end.
  • 相关阅读:
    华为手机wifi调试adb,断开数据线offlin
    appium 识别抖音视频已经播放完成
    对于学习新知识的一点自我反思
    部分软件激活
    AndroidStudio 创建简单的app
    App 逆向思路
    链家
    pyqt5 截屏
    3.无重复字符的最长子串
    1.两数之和
  • 原文地址:https://www.cnblogs.com/bobble/p/6849927.html
Copyright © 2011-2022 走看看