zoukankan      html  css  js  c++  java
  • 【NOIP2016】蚯蚓 --队列模拟

    【NOIP2016】蚯蚓

     

    话说去年这个题 我用priority_queue乱搞 结果惨不忍睹 

    q=0时送了50分 结果~~~~(>_<)~~~~  

    每次弹出最长的蚯蚓 把它切开 在放回队列 

    这个应该都能想到 

    只不过除了被切的蚯蚓 其他蚯蚓每秒都会增长 

    所以 我们可以用一个变量来记录增量

    每次我们只弹出 队列元素最大值 把它加上增长变量 再去切它

    并且保证队列里的元素都是减掉了增量的 

    注意 因为切得时候蚯蚓不会变长 所以放入队列的时候还要减去当前一秒增长的长度 

    这个题 数据比较大 所以用priority_queue会超时 我写priority_queue 只拿了75分 

     1 #include <cmath>
     2 #include <queue>
     3 #include <cstdio>
     4 #include <cctype>
     5 #include <algorithm>
     6 
     7 const int MAXN=5*1e7+10;
     8 
     9 int n,m,u,v,t,q,tag;
    10 
    11 std::priority_queue<int> Q;
    12 
    13 inline void read(int&x) {
    14     int f=1;register char c=getchar();
    15     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
    16     for(;isdigit(c);x=x*10+c-48,c=getchar());
    17     x=x*f;
    18 }
    19 
    20 int hh() {
    21     read(n);read(m);read(q);
    22     read(u);read(v);read(t);
    23     for(int x,i=1;i<=n;++i) read(x),Q.push(x);
    24     double p=(double)u/v;
    25     for(int i=1;i<=m;++i) {
    26         int now=Q.top();Q.pop();
    27         int L1=floor(p*(now+tag));
    28         int L2=(now+tag)-L1;
    29         Q.push(L1-tag-q);
    30         Q.push(L2-tag-q);
    31         if(i%t==0) printf("%d ",now+tag);
    32         tag+=q;
    33     }
    34     printf("
    ");
    35     for(int i=1;i<=n+m;++i) {
    36         int L=Q.top();Q.pop();
    37         if(i%t==0) printf("%d ",L+tag);
    38     }
    39     printf("
    ");
    40     return 0;
    41 }
    42 
    43 int sb=hh();
    44 int main(int argc,char**argv) {;}
    priority_queue

    正解是用三个队列模拟过程 

    一个队列存储原始蚯蚓 一个存储切了一半的蚯蚓 另一个存储另一半蚯蚓 

    每个蚯蚓在每一秒都会增长 

    当前蚯蚓被切以后 切成的两半分别都要小于对应队列的最小值

    换句话说 后两个队列都是单调递减的 

    因为 我们每次取出当前最长的蚯蚓 加上累积的长度 

    切开之后 再减去累积的长度 在减去一个q放入队列与其他数保持同步   也就是这一秒他没有增长

    可以看出整个操作没有加法操作 我们只是把一个蚯蚓切开后放入队列 这样显然  后切开的蚯蚓的长度小于之前切开的蚯蚓的长度

    显然 队列是单调的 

    当前蚯蚓最大值从三个队列的队首取就好了

    ps:不敢相信double了 在UOJ上被hack 就是double惹的祸 

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cctype>
     4 #include <algorithm>
     5 
     6 typedef long long LL;
     7 const int INF=0x7fffffff;
     8 const int MAXN=10000010; 
     9 
    10 int n,m,u,v,t,q,tag;
    11 
    12 int t1,h1,t2,h2,h3,t3;
    13 
    14 int q1[MAXN],q2[MAXN],q3[MAXN],q4[MAXN];
    15 
    16 inline void read(int&x) {
    17     int f=1;register char c=getchar();
    18     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
    19     for(;isdigit(c);x=x*10+c-48,c=getchar());
    20     x=x*f;
    21 }
    22 
    23 inline bool cmp(int a,int b) {return a>b;}
    24 
    25 inline int get() {
    26     int N1=-INF,N2=-INF,N3=-INF;
    27     if(h1<t1) N1=q1[h1];
    28     if(h2<t2) N2=q2[h2];
    29     if(h3<t3) N3=q3[h3];
    30     if(N1>=N2&&N1>=N3) {++h1;return N1;}
    31     if(N2>=N1&&N2>=N3) {++h2;return N2;}
    32     if(N3>=N2&&N3>=N1) {++h3;return N3;}
    33 }
    34 
    35 int hh() {
    36     read(n);read(m);read(q);read(u);read(v);read(t);
    37     for(int x,i=1;i<=n;++i) read(x),q1[t1++]=x;
    38     std::sort(q1,q1+t1,cmp);
    39 //    double p=(double)u/v;
    40     for(int i=1;i<=m;++i) {
    41         int now=get();
    42         LL L1=(LL)u*(now+tag)/v;
    43         LL L2=(LL)(now+tag)-L1;
    44         q2[t2++]=L1-tag-q;
    45         q3[t3++]=L2-tag-q;
    46         if(i%t==0) printf("%d ",now+tag);
    47         tag+=q;
    48     }
    49     printf("
    ");
    50     for(int i=1;i<=n+m;++i) {
    51         int now=get();
    52         if(i%t==0) printf("%d ",now+tag);
    53     }
    54     printf("
    ");
    55     return 0;
    56 }
    57 
    58 int sb=hh();
    59 int main(int argc,char**argv) {;}
    队列模拟
  • 相关阅读:
    grep 精确匹配
    @ARGV
    同时查看多个文件
    R画双y轴图
    R画饼图
    linux的sort排序
    $0
    QQ图
    Config::Std模块安装
    R语言做正态分布检验
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7582371.html
Copyright © 2011-2022 走看看