• 2019中山大学程序设计竞赛(重现赛)


    Triangle

    题意:给你n个木棒,判断其能否组成三角形。

    这题就是斐波那契数数列的应用,把斐波那契数列打出来,可以知道第47项就大于2^31-1了,于是的话,最长的不能构成三角形的序列的长度就是46了,若序列长度>=47,那就必有一个长度>=2的区间不满足斐波那契数列,那就可以构成,若序列长度<47就暴力判断。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=5e6+10;
    #define ll long long
    int a[maxn],n,flag;
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            flag=0;
            for(int i=1;i<=n;i++) scanf("%d",&(a[i]));
            if(n>=47)
            {
                flag=1;
    
            }
            else
            {
                sort(a+1,a+n+1);
                for(int i=3;i<=n;i++)
                    if(a[i-2]+a[i-1]>a[i])
                    {
                        flag=1;
                        break;
                    }
            }
            puts((flag==1)?"YES":"NO");
        }
       return 0;
    }

    Monitor

    题意就是一个n*m的矩阵,p个监控,q个小偷活动区域,对每个活动区域问是否能被监控区域完全覆盖。

    二维差分+二维前缀和,二维差分就是假如x1,y1,x2,y2对应区域的值加x,那么直接对差分数组c[x1][y1]+=x,  c[x2+1][y2+1]+=x,

    c[x2+1][y1]-=x,c[x1][y2+1]-=x,然后再对c数组求一次二维前缀和就可以得到每一个位置的变化值了(可以和一维的类比),顺便学了手开动态二维数组,利用指针开动态二维数组我不会,就用vector开了

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,p,q;
    
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            vector<int>c[n+10];
            for(int i=0;i<=n+5;i++)
                for(int j=0;j<=m+5;j++)
                   c[i].push_back(0);
            scanf("%d",&p);
            for(int i=1;i<=p;i++)
            {
                int xo,yo,xt,yt;
                scanf("%d%d%d%d",&xo,&yo,&xt,&yt);
                c[xo][yo]++,c[xt+1][yt+1]++,c[xt+1][yo]--,c[xo][yt+1]--;
            }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                {
                    c[i][j]+=c[i-1][j]+c[i][j-1]-c[i-1][j-1];
                }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                {
                    if(c[i][j]>=1) c[i][j]=1;
                    c[i][j]+=c[i-1][j]+c[i][j-1]-c[i-1][j-1];
                }
            scanf("%d",&q);
            while(q--)
            {
                int xo,yo,xt,yt;
                scanf("%d%d%d%d",&xo,&yo,&xt,&yt);
                if((c[xt][yt]-c[xt][yo-1]-c[xo-1][yt]+c[xo-1][yo-1])==((xt-xo+1)*(yt-yo+1)))
                    printf("YES
    ");
                else
                    printf("NO
    ");
            }
        }
        return 0;
    }
    

    http://acm.hdu.edu.cn/showproblem.php?pid=6521

    Party

    有n个人,然后有m个派对,问你每个派对上有多少对人是新认识的。

    推荐一篇大佬的博客,讲的很清楚  https://blog.csdn.net/u013534123/article/details/89409912  

    我是在其基础上优化了一些,定义一个R[]数组,表示的是每个人认识的最右边的人,然后因为区间是连续的,所以R[]数组是非严格单调递增的,对于一个区间l到r,新认识的人的对数就是r*(pos-l+1)-sum(R[i],l<=i<=pos),这里pos表示的是满足R[i]<=r的最大的pos,pos位置可以用线段树维护。感觉每次写线段树,找bug都能找一天qwq。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ls rt<<1
    #define rs rt<<1|1
    const int maxn=5e5+10;
    struct node
    {
        int maxx,l,r,lazy;
        ll sum;
        node(ll sum=0LL,int maxx=0,int l=0,int r=0,int lazy=0)
        {
            this->sum=sum;
            this->maxx=maxx;
            this->l=l;
            this->r=r;
            this->lazy=lazy;
        }
    }tree[maxn<<2];//tree维护的是r数组
    void pushup(int rt)
    {
        tree[rt].sum=tree[ls].sum+tree[rs].sum;
        tree[rt].maxx=max(tree[ls].maxx,tree[rs].maxx);
    }
    void pushdown(int rt)
    {
        if(tree[rt].lazy)
        {
            tree[ls].lazy=tree[rs].lazy=tree[rt].lazy;
            tree[ls].sum=1LL*(tree[ls].r-tree[ls].l+1)*tree[ls].lazy;
            tree[rs].sum=1LL*(tree[rs].r-tree[rs].l+1)*tree[rs].lazy;
            tree[ls].maxx=tree[rs].maxx=tree[rt].lazy;
            tree[rt].lazy=0;
        }
    }
    void build(int rt,int l,int r)
    {
        tree[rt].l=l,tree[rt].r=r;
        tree[rt].lazy=0;
        if(l==r)
        {
            tree[rt].sum=tree[rt].maxx=l;
            return ;
        }
        int mid=(l+r)>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        pushup(rt);
    }
    int querypos(int rt,int x)
    {
        if(tree[rt].l==tree[rt].r)
        {
            if(tree[rt].maxx<=x)
                return tree[rt].l;
            else
                return -1;
        }
        pushdown(rt);
        if(tree[ls].maxx<=x)
            return max(tree[ls].r,querypos(rs,x));
        else
            return querypos(ls,x);
    }
    ll querysum(int rt,int l,int r)
    {
        if(tree[rt].l>=l&&tree[rt].r<=r)
            return tree[rt].sum;
        int mid=(tree[rt].l+tree[rt].r)>>1;
        pushdown(rt);
        if(mid>=r)
            return querysum(ls,l,r);
        else
            if(mid<l)
                return querysum(rs,l,r);
            else
                return querysum(ls,l,mid)+querysum(rs,mid+1,r);
    }
    void update(int rt,int l,int r,int val)
    {
        if(tree[rt].l>=l&&tree[rt].r<=r)
        {
            tree[rt].lazy=val;
            tree[rt].maxx=val;
            tree[rt].sum=1LL*(tree[rt].r-tree[rt].l+1)*val;
            return ;
        }
        int mid=(tree[rt].l+tree[rt].r)>>1;
        pushdown(rt);
        if(mid>=r)
            update(ls,l,r,val);
        else
            if(mid<l)
                update(rs,l,r,val);
            else
                update(ls,l,mid,val),update(rs,mid+1,r,val);
        pushup(rt);
    }
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            build(1,1,n);
            while(m--)
            {
                ll ans;
                int l,r,pos;
                scanf("%d%d",&l,&r);
                pos=querypos(1,r);
                if(pos<=l-1)
                    ans=0LL;
                else
                    ans=1LL*r*(pos-l+1)-1LL*querysum(1,l,pos),update(1,l,pos,r);
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    OJ 之 FATE
    hdu 1701 (Binary Tree Traversals)(二叉树前序中序推后序)
    POJ 1789 Truck History
    数据结构之 普利姆算法总结
    HDU OJ 2159 FATE
    The Great Pan
    2014年的暑假ACM之旅!
    0-1背包问题
    中国剩余定理的解释!
    POJ 1183 反正切函数的应用
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754776.html
Copyright © 2020-2023  润新知