zoukankan      html  css  js  c++  java
  • The 13th Chinese Northeast Collegiate Programming Contest

    题目列表


    B - Balanced Diet

    题意: 给你m种食物,给你1~m个L[i]表示如果你要取第i种食物,你至少要取L[i]个。再给你n个食物,有n个a[i]和b[i]分别表示食物的价值和种类,设U为食物的总价值,V为所有种类的食物中数量最大的种类的数量,问U/V的最大值是多少。
    思路:首先我们看取某种食物的顺序,因为U越大越好,因此每类食物都要从大到小排序,然后枚举每个分母V的值,那么分母U的值也就是在符合L[i]的前提下取第i种食物的前V项即可。
    代码:

    ‘’‘’‘’
    const int maxn = 100005;
    inline ll gcd(ll a,ll b) {
        return b>0 ? gcd(b,a%b):a;
    }
    struct node{
        int l,id;
    }ss[maxn];
    int n,m;
    vector<int>swt[maxn];
    vector<int>sum[maxn];
    bool cmp(int x,int y)
    {
        return x>y;
    }
    int main()
    {
        int T;
        cin>>T;
        while(T--){
            scanf("%d %d",&n,&m);
            for(int i=1;i<=max(n,m);i++){
                swt[i].clear();
                sum[i].clear();
            }
            for(int i=1;i<=m;i++){
                scanf("%d",&ss[i].l);
                ss[i].id=i;
            }
            for(int i=1;i<=n;i++){
                int x,y;
                scanf("%d %d",&x,&y);
                swt[y].push_back(x);
            }
            for(int i=1;i<=m;i++){
                sort(swt[i].begin(),swt[i].end(),cmp);
          for(int j=0;j<swt[i].size();j++){
                    sum[max(j+1,ss[i].l)].push_back(swt[i][j]);
                }
            }
            ll mm=0,zz=0,nm=1,nz=0;
            for(int i=1;i<=n;i++){
                mm=i;
            for(int j=0;j<sum[i].size();j++){
                    zz+=sum[i][j];
              }
                f(1ll*nm*zz>1ll*nz*mm){
                    nm=mm;
                    nz=zz;
                }
            }
            ll pp=gcd(nz,nm);
          printf("%lld/%lld
    ",nz/pp,nm/pp);
        }
        return 0;
     }
    
    

    C - Line-line Intersection

    思路:两条直线不平行则必相交,若平行:若相交那么答案+1,否则不算。两个map去储存,第一个map储存某一斜率下平行的数量,第二个map储存某一条直线的重合数量。在添加第i条直线时,答案ans=i-平行数量+重合数量。
    代码:

    ‘’‘’‘’
    map<pair<ll,ll>,ll>k;
    map<pair<pair<ll,ll>,ll>,ll>c;
    int main()
    {
        int n,t;
        t=read();
        while(t--)
        {
            n=read();
            ll ans=0;
            k.clear();
            c.clear();
            for(int i=0;i<n;i++)
            {
                ll x1,y1,x2,y2,x;
                scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
                x=x1*y2-x2*y1;
                ll xx=x2-x1;
                ll yy=y2-y1;
                ll d=__gcd(xx,yy);
                xx/=d;
                yy/=d;
                x/=d;
                ans+=i-k[{xx,yy}]+c[{{xx,yy},x}];
                k[{xx,yy}]++;
                c[{{xx,yy},x}]++;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    

    E - Minimum Spanning Tree

    题意:给你一幅图,把边看成点,有公共点的两条边就是有一条连边的两个点,边权就是两条边的边权之和,让你构造一颗最小生成树,问你边权之和是多少。
    思路:我们从每条边的贡献入手,显然,一个点的所有出边中,我们要用到最多的就是最小边,最小边要和可以和它相连的所有边相连,则其贡献就是(出边数-1)*w,对于其它边,要保证连通,都会用到一次。
    代码:

    vector<ll>g[maxn];
    int main()
    {
        ll T,n;
        cin>>T;
        while(T--){
            scanf("%lld",&n);
            for(int i=1;i<=n;i++){
                g[i].clear();
            }
            for(int i=1;i<n;i++){
                ll u,v,w;
                scanf("%lld %lld %lld",&u,&v,&w);
                g[u].push_back(w);
                g[v].push_back(w);
            }
            ll ans=0;
            ll res=0;
            ll minn=INF;
            for(int i=1;i<=n;i++){
                res=0;
                minn=INF;
                if(g[i].size()<=1)continue;
                for(int j=0;j<g[i].size();j++){
                    ll u=g[i][j];
                    res+=u;
                    minn=min(minn,u);
                }
                res+=(g[i].size()-2)*minn;
                ans+=res;
            }
            printf("%lld
    ",ans);
        }
        return 0;
     }
    

    G - Radar Scanner

    题意:在二维平面上,给你n个矩形的左下角和右上角坐标,一次移动可以选择一个矩形向上下左右移动一格。问你最少多少次移动可以让所有矩形有一个公共相交点。
    思路:首先是二维平面上的问题,且相互独立,那么可以转化为一维问题。就是若干条直线,最少移动多少次有公共点。猜一下是移到所有点的中位数就是最小。
    代码:

    ‘’‘’‘’
    const int maxn = 100005;
    vector<ll>g[maxn];
    int main()
    {
        ll T,n;
        cin>>T;
        while(T--){
            scanf("%lld",&n);
            for(int i=1;i<=n;i++){
                g[i].clear();
            }
            for(int i=1;i<n;i++){
                ll u,v,w;
                scanf("%lld %lld %lld",&u,&v,&w);
                g[u].push_back(w);
                g[v].push_back(w);
            }
            ll ans=0;
            ll res=0;
            ll minn=INF;
            for(int i=1;i<=n;i++){
                res=0;
                minn=INF;
                if(g[i].size()<=1)continue;
                for(int j=0;j<g[i].size();j++){
                    ll u=g[i][j];
                    res+=u;
                    minn=min(minn,u);
                }
                res+=(g[i].size()-2)*minn;
                ans+=res;
            }
            printf("%lld
    ",ans);
        }
        return 0;
     }
    
    

    H - Skyscraper

    题意:n座摩天大楼,每座的预计层高为a[i]。
    m次操作:
    1、将a的某个区间[l , r]加上k。
    2、询问仅对[l, r]区间从0开始施工,最少需 要几个阶段。
    每一个阶段操作,可以任意选取一个区间,在这个区间上每个a[i]加上1 。
    思路:
    ** 1、首先令b[I]=a[I]-a[i-1] 。
    ** 2、b[i]>0,那么要多花b[i]个阶段才能把a[i]修好。
    ** 3、b[i]<=0,那么在修a[i-1]时就可以把a[i]顺带着修好。
    ** 4、那么令c[I]=b[i] (b[ I]>0),就表示在修好i-1这个楼后要修i这个楼需要的阶段。
    ** 5、那么对于区间[l,r]需要的阶段就是a[l]+c[l+1]+c[l+2]+……+c[r-1]+c[r]。
    ** 6、也就是(b[1]+b[2]+……+b[l])+(c[l+1]+c[l+2]+……+c[r-1]+c[r])。
    ** 7、对于区间加的操作,我们只需要在b和c数组的l处加上k,r+1处减去k,即可。
    ** 8、用树状数组维护前缀和即可。
    代码:

    ‘’‘’‘’
    const int maxn = 100005;
    
    ll a[maxn],b[maxn],c[maxn];
    ll T,n,m;
    struct tr{
        ll sum[maxn];
        void add(int p,ll x){
            while(p<=n){
                sum[p]+=x;
                p+=p&(-p);
            }
        }
        ll ask(int p){
            ll res=0;
            while(p){
                res+=sum[p];
                p-=p&(-p);
            }
            return res;
        }
        ll r_ask(int l,int r){
            return ask(r)-ask(l-1);
        }
    }tb,tc;
    int main()
    {
        cin>>T;
        while(T--){
            for(int i=1;i<maxn;i++){
                tb.sum[i]=0;
                tc.sum[i]=0;
                b[i]=0;
            }
            scanf("%lld %lld",&n,&m);
            for(int i=1;i<=n;i++){
                scanf("%lld",&a[i]);
                if(i>=2){
                    b[i]=a[i]-a[i-1];
                    tb.add(i, b[i]);
                    if(b[i]>0){
                        tc.add(i, b[i]);
                    }
                }else{
                    b[i]=a[i];
                    tb.add(i, a[i]);
                    tc.add(i, a[i]);
                }
            }
            int op,l,r,x;
            while(m--){
                scanf("%d",&op);
                if(op==1){
                    scanf("%d %d %d",&l,&r,&x);
                    tb.add(l, x);
                    tb.add(r+1,-x);
                    if(b[l]>0){
                        tc.add(l, x);
                    }else if(b[l]+x>0){
                        tc.add(l, b[l]+x);
                    }
                    if(b[r+1]>0){
                        if(b[r+1]-x>0){
                            tc.add(r+1, -x);
                        }else{
                            tc.add(r+1, -b[r+1]);
                        }
                    }
                    b[l]+=x;
                    b[r+1]-=x;
                }else{
                    scanf("%d %d",&l,&r);
                    printf("%lld
    ",tb.r_ask(1,l)+tc.r_ask(l+1,r));
                }
            }
        }
        return 0;
     }
    

    J - Time Limit

    代码:

    ‘’‘’‘’
    #include<bits/stdc++.h>
    using namespace std;
    int t,a[1001],n;
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            int k=3*a[1];
           
            for(int i=2;i<=n;i++)
            {
               k=max(k,1+a[i]);
            }
            if(k%2==0) printf("%d
    ",k);
            else printf("%d
    ",k+1);
        }
        return 0;
    }
    

    记 2020 9.5 组队训练

    越自律,越自由
  • 相关阅读:
    ZOJ 3349 Special Subsequence
    ZOJ 3684 Destroy
    ZOJ 3820 Building Fire Stations
    HDU 5291 Candy Distribution
    HDU 3639 Hawk-and-Chicken
    HDU 4780 Candy Factory
    HDU 4276 The Ghost Blows Light
    ZOJ 3556 How Many Sets I
    技术人员的眼界问题
    神经网络和深度学习
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/13621925.html
Copyright © 2011-2022 走看看