• 2017CCPC'S Xiangtan


    Time:Solo

    Link


    A

    题意

    分析


    B

    题意

    分析


    C

    题意

    分析


    D

    签到 


    E

    题意

    分析

    ym:前缀和排序后贪心取即可,注意要0加进去,表示到起点开始!! 

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    int t,a[100007],sum[100007],n,m,c;
    bool vis[100007];
    ll ans=0;
    
    int main()
    {
        while(scanf("%d%d%d",&n,&m,&c)!=EOF)
        {
            ans=0;
            memset(sum,0,sizeof(sum));
            memset(vis,false,sizeof(vis));
       // scanf("%d%d%d",&n,&m,&c);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        sort(sum,sum+n+1);
        int l=0,r=n;
        ll tmp=0;
        for(int i=1;i<=m;i++)
        {
            tmp+=sum[r]-sum[l]-c;
            r--;
            l++;
            ans=max(ans,tmp);
        }
        cout<<ans<<endl;
        }
        return 0;
    }

    F

    题意

    分析


    G

    题意

    分析

     ym:贪心的将左括号变成右括号,有优先队列贪心的维护一下这个过程即可

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int maxn = 1e5+7;
    char s[5];
    ll sum[maxn];
    
    struct node
    {
        ll num,w;
        node(){}
        node(int x,int y){num=x,w=y;}
        friend bool operator < (node a,node b)
        {
            return a.w>b.w;
        }
    }a[maxn];
    
    priority_queue<node>q;
    int n;
    ll ans=0;
    
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            ans=0;
            while(!q.empty())q.pop();
            for(int i=1;i<=n;i++)
            {
                scanf("%lld%s%lld",&a[i].num,s,&a[i].w);
                sum[i]=sum[i-1]+a[i].num;
                if(s[0]=='(')
                {
                    ans+=a[i].w*a[i].num;
                    a[i].w=-a[i].w;
                }
            }
            ll l=0;
            for(int i=1;i<=n;i++)
            {
                q.push(a[i]);
                ll ca=(sum[i]+1)/2-l;
                l=(sum[i]+1)/2;
                while(ca)
                {
                    node now=q.top();
                    q.pop();
                    if(now.num>ca)
                    {
                        ans+=now.w*ca;
                        now.num-=ca;
                        ca=0;
                        q.push(now);
                    }
                    else
                    {
                        ans+=now.w*now.num;
                        ca-=now.num;
                    }
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }

    H

    题意

    分析

    ym:树上任意一点距离最远的点一定是树的直径两个点中的一个,三次dfs即可

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const int maxn = 2e5+7;
    
    int tot,head[maxn*2],nxt[maxn*2],to[maxn*2];
    ll w[maxn*2];
    int n,u,v;
    ll c;
    ll maxx;
    int ml,mr;
    ll d1[maxn],d2[maxn],ans;
    
    void add(int u,int v,ll c)
    {
        to[++tot]=v;
        w[tot]=c;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    
    void dfs1(int x,int fa,ll sum)
    {
        if(sum>maxx)
        {
            maxx=sum;
            ml=x;
        }
        for(int i=head[x];i;i=nxt[i])
        {
            int v=to[i];
            if(v==fa) continue;
            dfs1(v,x,sum+w[i]);
        }
    }
    
    void dfs2(int x,int fa,ll sum)
    {
        d1[x]=sum;
        if(sum>maxx)
        {
            maxx=sum;
            mr=x;
        }
        for(int i=head[x];i;i=nxt[i])
        {
            int v=to[i];
            if(v==fa) continue;
            dfs2(v,x,sum+w[i]);
        }
    }
    
    
    void dfs3(int x,int fa,ll sum)
    {
        d2[x]=sum;
        for(int i=head[x];i;i=nxt[i])
        {
            int v=to[i];
            if(v==fa) continue;
            dfs3(v,x,sum+w[i]);
        }
    }
    
    int main()
    {
    
        while(scanf("%d",&n)!=EOF)
        {
            if(n==0)
                break;
            ans=0;
            tot=0;
            memset(d1,0,sizeof(d1));
            memset(d2,0,sizeof(d2));
            memset(head,0,sizeof(head));
            memset(nxt,0,sizeof(nxt));
            memset(w,0,sizeof(w));
            memset(to,0,sizeof(to));
        for(int i=1;i<=n-1;i++)
        {
            scanf("%d%d%lld",&u,&v,&c);
            add(u,v,c),add(v,u,c);
        }
    
        maxx=0;
        dfs1(1,0,0);
        maxx=0;
        dfs2(ml,0,0);
        maxx=0;
        dfs3(mr,0,0);
        ans=d1[mr];
        for(int i=1;i<=n;i++)
        {
           if(i!=mr&&i!=ml) ans+=max(d1[i],d2[i]);
        }
        ///ans+=max(max(d1[ml],d1[mr]),max(d2[ml],d2[mr]));
        cout<<ans<<endl;
        }
        return 0;
    }

    I

    ym:猜一下???


    J

    题意

    分析


    Summary

    Ym

    Czh

  • 相关阅读:
    【LeetCode】Binary Tree Upside Down
    【LeetCode】171. Excel Sheet Column Number
    【LeetCode】Longest Substring with At Most Two Distinct Characters (2 solutions)
    【Algorithm】回溯法与深度优先遍历的异同
    【C++】自定义比较函数小结
    【LeetCode】4. Median of Two Sorted Arrays (2 solutions)
    【LeetCode】3. Longest Substring Without Repeating Characters (2 solutions)
    【LeetCode】Add Two Numbers
    【LeetCode】5. Longest Palindromic Substring
    【LeetCode】6. ZigZag Conversion
  • 原文地址:https://www.cnblogs.com/Deadline/p/8987166.html
Copyright © 2020-2023  润新知