• [NOIP模拟16]题解


    A.Blue

    出题人大概已经去为国家处理积压子弹了?

    贪心,让每一只青蛙(我怂行吧)都尽量往远跳,能到达的最远的被踩了就跳次远的,以此类推。可以维护一个单调队列,表示每只青蛙的位置(开始都是0)。然后按顺序扫一遍每个石头,如果队首的青蛙不能跳过去就放弃它直接pop掉,如果能跳就把石头位置从队尾push进去并pop掉队首的旧位置,最后队列的size就是答案。因为你肯定不能可着一个青蛙往前跳,必须尽量不让任何一只掉队,所以一只跳完之后把它丢到队尾。

    比较神奇的是这道题用STL会比手写队列快300ms??

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=1e6+5;
    int T,n,m,D,L;
    int a[N];
    void work()
    {
        cin>>n>>m>>D>>L;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        a[n+1]=L;
        deque<int> q;
        for(int i=1;i<=m;i++)q.push_back(0);
        for(int i=1;i<=n+1;i++)
        {
            while(!q.empty()&&q.front()+D<a[i])q.pop_front();
            q.push_back(a[i]);q.pop_front();
        }
        if(q.size()==m)puts("Excited");
        else printf("%d
    ",q.size());
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>T;
        while(T--)work();
        return 0;
    }
    STL:deque
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=1e6+5;
    int T,n,m,D,L;
    int a[N],q[N];
    void work()
    {
        cin>>n>>m>>D>>L;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        a[n+1]=L;
        memset(q,0,sizeof(q));
        int head=1,tail=m;
        for(int i=1;i<=n+1;i++)
        {
            while(head<=tail&&q[head]+D<a[i])head++;
            q[++tail]=a[i];head++;
        }
        if(tail-head+1==m)puts("Excited");
        else printf("%d
    ",tail-head+1);
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>T;
        while(T--)work();
        return 0;
    }
    数组

    B.Weed

    好题,先咕着

    用线段树维护操作的题还是第一次见

    线段树上的区间指的是一段连续的操作区间,而不是实际的序列

    维护$add$(加了多少层)$del$(删了多少层)$sum$(有多少量)$lsum(被兄弟删除后的量,仅对左儿子维护)$

    $up()$的时候如果左儿子不够右儿子删,直接清0即可。但要是右儿子删不完左儿子就很麻烦了。需要专门设计一个函数计算当前区间中删了x个元素的和。

    (于是我又懒癌发作了)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-'0',ch=getchar();}
        return x*f;
    }
    const int N=2e5+55;
    #define ls(k) k<<1
    #define rs(k) k<<1|1
    int m,Q;
    struct ques
    {
        int op,val;
    }q[N];
    int del[N<<2],add[N<<2],lsum[N<<2],sum[N<<2];
    int query(int k,int val)
    {
        if(val==add[rs(k)])return lsum[ls(k)];
        if(val>add[rs(k)])return query(ls(k),val-add[rs(k)]+del[rs(k)]);
        if(val<add[rs(k)])return lsum[ls(k)]+query(rs(k),val);
    }
    void up(int k)
    {
        if(add[ls(k)]<=del[rs(k)])
        {
            lsum[ls(k)]=0;
            sum[k]=sum[rs(k)];
            add[k]=add[rs(k)];
            del[k]=del[rs(k)]+del[ls(k)]-add[ls(k)];
        }
        else
        {
            del[k]=del[ls(k)];
            add[k]=add[ls(k)]+add[rs(k)]-del[rs(k)];
            if(del[rs(k)])lsum[ls(k)]=query(ls(k),del[rs(k)]);
            else lsum[ls(k)]=sum[ls(k)];
            sum[k]=sum[rs(k)]+lsum[ls(k)];
        }
    }
    void build(int k,int l,int r)
    {
        if(l==r)
        {
            if(q[l].op==0)add[k]=1,sum[k]=lsum[k]=q[l].val;
            else del[k]=q[l].val;
            return ;
        }
        int mid=l+r>>1;
        build(ls(k),l,mid);build(rs(k),mid+1,r);
        up(k);
    }
    void update(int k,int l,int r,int pos,int op,int val)
    {
        if(l==r)
        {
            lsum[k]=add[k]=sum[k]=del[k]=0;
            if(op)
                del[k]=val;
            else
                add[k]=1,sum[k]=lsum[k]=val;
            return ;
        }
        int mid=l+r>>1;
        if(pos<=mid)update(ls(k),l,mid,pos,op,val);
        else update(rs(k),mid+1,r,pos,op,val);
        up(k);
    }
    int main()
    {
        /*freopen("weed.in","r",stdin);
        freopen("my.out","w",stdout);*/
        m=read();Q=read();
        for(int i=1;i<=m;i++)
            q[i].op=read(),q[i].val=read();
        build(1,1,m);
        for(int i=1;i<=Q;i++)
        {
            int num=read(),op=read(),val=read();
            update(1,1,m,num,op,val);
            printf("%d
    ",sum[1]);
        }
        return 0;
    }
    View Code

    C.Drink

    没有打恶心至极的大常数正解,其实优化暴力+卡常跑出来和正解的时间相差无几。

    %%%WHS式循环展开 TQL 帅过WYS

     优化暴力的思路就是每层矩形只枚举最上面的那条边上的点,因为有了这条边上一个点的坐标就可以完成矩形上四个点的旋转,所以只枚举一条边上的点就能完成整个矩形的旋转。

    然后调整边长和左上角坐标,对每层矩形都来一遍就好了。复杂度其实相比最暴力的没有变,但是循环次数少了,相当于一种循环展开。

    当然还要稍作卡常,$int$转$char$  $getchar$读入  $putchar$输出啥的

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define re register
    using namespace std;
    const int N=3005;
    int n,m,Q,x,y,c;
    char a[N][N],b[N][N];
    inline int read()
    {
        re int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    int main()
    {
        n=read();m=read();Q=read();
        for(re int i=1;i<=n;i++)
            for(re int j=1;j<=m;j++)
            {
                a[i][j]=getchar();
                while(!isdigit(a[i][j]))a[i][j]=getchar();
            }
        while(Q--)
        {
            x=read();y=read();c=read();
            for( ;c>1;c-=2,x++,y++)
            {
                re int L=y,U=x,D=x+c-1,R=y+c-1;
                for(re int i=0;i<=c-2;i++)
                {
                    char old=a[U+i][R];
                    a[U+i][R]=a[U][L+i];
                    a[U][L+i]=a[D-i][L];
                    a[D-i][L]=a[D][R-i];
                    a[D][R-i]=old;
                }
            }
        }
        for(re int i=1;i<=n;i++)
        {
            for(re int j=1;j<=m;j++)
                putchar(a[i][j]),putchar(' ');
            putchar('
    ');
        }
        return 0;
    }
    View Code
  • 相关阅读:
    hdu-2544-最短路(Bellman-Ford算法模板)
    hdu-2544-最短路(dijkstra算法模板)
    C++结构体成员列表初始化
    hdu-3790-最短路径问题(Dijkstra)
    hdu--1878--欧拉回路(并查集判断连通,欧拉回路模板题)
    nyoj-1278-Prototypes analyze(二叉排序树模板)
    hdu-5183-Negative and Positive (NP)(hash模板)
    nyoj-130-相同的雪花(hash)
    01 格式化输出
    003 标准数据类型简介 + 数字类型
  • 原文地址:https://www.cnblogs.com/Rorschach-XR/p/11333782.html
Copyright © 2020-2023  润新知