• 洛谷 1440 求m区间内的最小值


                洛谷  1440 求m区间内的最小值

    题目描述

    一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值。若前面的数不足m项则从第1个数开始,若前面没有数则输出0。

    输入输出格式

    输入格式:

    第一行两个数n,m。

    第二行,n个正整数,为所给定的数列。 

    输出格式:

    n行,第i行的一个数ai,为所求序列中第i个数前m个数的最小值。

    题解:

    偷偷告诉你,我超级喜欢暴力的。所以看到这个题的第一反应,就是打暴力

     1 // luogu-judger-enable-o2
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 using namespace std;
     8 int a[2000010],n,m;
     9 int main(){
    10     scanf("%d%d",&n,&m);
    11     for(int i=1;i<=n;i++)
    12         scanf("%d",&a[i]);
    13     cout<<0<<endl;
    14     for(int i=2;i<=n;i++){
    15         int s=i-m,minn=999999999;
    16         if(s<1)
    17             s=1;
    18         for(int j=s;j<i;j++)
    19             minn=min(minn,a[j]);
    20         cout<<minn<<endl;
    21     }
    22     return 0;
    23 }

    hhh,没想到,居然有50分;

    next,我还是想不出正解,因为那时候刚学队列然而我对队列无感,对于讲队列的学长更是,emmm。在这里吐槽一句,他的代码实在是太丑了。

    然后,我就开始想方设法,为所欲为的给它提速,然后加了一个特判

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int a[2000010],n,m,minn=999999999,minp;
     8 int main(){
     9     scanf("%d%d",&n,&m);
    10     for(int i=1; i<=n; i++)
    11         scanf("%d",&a[i]);
    12     cout<<0<<endl;
    13     for(int i=2; i<=n; i++){
    14         int s=i-m;
    15         if(s<1) s=1;
    16         if(a[i-1]<=minn) minn=a[i-1],minp=i-1;
    17         if(minp<s){
    18             minn=a[s],minp=s;
    19             for(int j=s; j<i; j++)
    20                 if(a[j]<=minn) 
    21                     minn=a[j],minp=j;
    22         }
    23         cout<<minn<<endl;
    24     }
    25     return 0;
    26 }

    然后,居然70了,哇,amazing。

    最后呢,听一位学长说,cout输出‘ ’比printf或者输出endl快,就试了一哈子。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int a[2000010],n,m,minn=999999999,minp;
     8 int main(){
     9     scanf("%d%d",&n,&m);
    10     for(int i=1; i<=n; i++)
    11         scanf("%d",&a[i]);
    12     cout<<0<<endl;
    13     for(int i=2; i<=n; i++){
    14         int s=i-m;
    15         if(s<1) s=1;
    16         if(a[i-1]<=minn) minn=a[i-1],minp=i-1;
    17         if(minp<s){
    18             minn=a[s],minp=s;
    19             for(int j=s; j<i; j++)
    20                 if(a[j]<=minn) 
    21                     minn=a[j],minp=j;
    22         }
    23         cout<<minn<<"
    ";
    24     }
    25     return 0;
    26 }

    这样居然A了,简直了。

    不过呢,还是要尊重正解。

     1 #include<complex>
     2 #include<cstdio>
     3 using namespace std;
     4 const int N=2e6+7;
     5 int n,m,head=1,tail,a[N],q[N];
     6 int main() {
     7     scanf("%d%d",&n,&m);
     8     for(int i=1; i<=n; i++)
     9         scanf("%d",&a[i]);
    10     q[++tail]=1;
    11     printf("0
    ");
    12     for(int i=2; i<=n; i++) {
    13         printf("%d
    ",a[q[head]]);
    14         if(q[head]<=i-m)head++;
    15         while(head<=tail && a[q[tail]]>=a[i])
    16             tail--;
    17         q[++tail]=i;
    18     }
    19     return 0;
    20 }

    正解是队列。

    题目说完了,进入吐槽时间。

    吐槽:

    讲队列的那位学长真的是,我第一次听他讲课的时候还没有感觉他长的那么惨无人道,惨绝人寰。现在真是越看越,emmm。话说他给我们布置的题目,说是用队列做的,我全没用队列,全用的暴力诶,哎也不是不想写队列,emmm,不会啊,现在更是好久没复习队列了,感觉队列和栈都快分不清楚了。哎,看来我有必要继续颓废了。hhh

    最后祝大家,大吉大利,今晚吃鸡啊哈。

    一世安宁

  • 相关阅读:
    Asp.net MVC 自定义路由在IIS7以上,提示Page Not Found 解决方法
    mysql 常用操作
    Mongo常用操作
    Cent Os 常用操作
    Window 8.1 开启Wifi共享
    解决 对象的当前状态使该操作无效 的问题
    unity3d: how to display the obj behind the wall
    unreal network
    rust borrow and move
    erlang的map基本使用
  • 原文地址:https://www.cnblogs.com/GTBA/p/9027979.html
Copyright © 2020-2023  润新知