• CCPC2017湘潭 1263 1264 1267 1268


    1263

    拉升一下就A了

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <queue>
    #define LL long long int
    using namespace std;
    
    int main()
    {
        cin.sync_with_stdio(false);
        int n,m,a,b;
        while(cin>>n>>m>>a>>b)
        {
            string s[105];
            for(int i=0;i<n;i++)
            {
                cin>>s[i];
            }
            for(int i=0;i<n*a;i++)
            {
                for(int j=0;j<m*b;j++)
                {
                    int y=i/a;
                    int x=j/b;
                    cout<<s[y][x];
                }
                cout<<endl;
            }
        }
    
        return 0;
    }

    1264

    这题特点是区间端点不可多次选取,然后在此情况下求前k大的区间和(根据C做一下处理就好)

    妈蛋XTUOJ把咱代码吞了,反正不长,再敲一遍。

    #include <iostream>
    #include <map>
    #include <vector>
    #include <algorithm>
    #include <set>
    #include <queue>
    #define LL long long int
    using namespace std;
    LL n,m,c;
    LL num[1000006];
    LL pre[1000006];
    int main()
    {
        cin.sync_with_stdio(false);
        while(cin>>n>>m>>c)
        {
            for(int i=0;i<n;i++)
            {
                cin>>num[i];
                if(i==0)
                    pre[i]=num[i];
                else
                    pre[i]=pre[i-1]+num[i];
            }
            pre[n]=0;
            sort(pre,pre+n+1);
            LL ans=0;
            for(int i=0;i<=n&&i<m;i++)
            {
                LL l=i;
                LL r=n-i;
                if(l>r||pre[r]-pre[l]<c)
                    break;
                ans+=pre[r]-pre[l]-c;
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    1267

    题意简单来说就是一棵树根据两点之间的路径长度作为建边费用,求最大生成树。

    感谢江理小伙伴提供思路,咱是死在赛场上都没想到用直径的特点。

    首先已知树最长的边是其直径,前n-1长的边一定和直径的某个点相连。

    证明:
    设直径左右两点A B
    任何点都直接间接连接至A,B
    设一个中间点C在AB直径上,对于一个点D,如果它在直径上,则把C当作D,DC=0,否则DC长度为DC本身
    假设点D到E的距离大于到A的距离且大于到D的距离,有
    DE>=AC+CD//假设
    DE>=BC+CD
    AB>=AC+CD+DE//AB直径
    AB>=BC+CD+DE
    ==>     AB*2+DE*2>=AB*2+DE*2+CD*4
    <==>    0>=CD*4,若CD<0与事实相悖。
    假设CD=0,那么D可以当作在直径上
    DE>=AC
    ==> DE>=AD
    DE>=BC
    ==> DE>=BD
    不妨设AD>=BD
    有DE+AC>=BD+AD
    ==> AD>=AB,当且仅当AD是多条直径中的一条时成立有AD==AB成立,不然均与结论相悖。
    证毕。 

    所以前n-1长的边就是直径加上剩余所有点到直径两端点距离最大值的和了。

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <queue>
    #define LL long long int
    using namespace std;
    struct node
    {
        LL p,d;
    };
    vector<node> g[100005];
    
    LL n,a,b,c;
    LL st,en;
    bool vis[100005];
    LL dis[100005];
    node dfs(LL now,LL dis)
    {
        node rec;
        rec.p=-1;
        if(vis[now])
        {
             return rec;
        }
        vis[now]=true;
    
        rec.p=now,rec.d=dis;
        for(int i=0;i<g[now].size();i++)
        {
    
            node px=dfs(g[now][i].p,dis+g[now][i].d);
    
            if(px.p==-1) continue;
            else
            {
                if(rec.p==-1) rec=px;
                else if(px.d>rec.d) rec=px;
            }
        }
        return rec;
    }
    void bfs(LL fr)
    {
        queue<node> q;
        q.push((node){fr,0});
        vis[fr]=true;
        while(!q.empty())
        {
            node now=q.front();
            q.pop();
            if(now.d>dis[now.p])
                dis[now.p]=now.d;
            for(int i=0;i<g[now.p].size();i++)
            {
                node nx=g[now.p][i];
                if(vis[nx.p]==false)
                {
                    q.push((node){nx.p,now.d+nx.d});
                    vis[nx.p]=true;
                }
            }
        }
    }
    
    int main()
    {
        cin.sync_with_stdio(false);
        while(cin>>n)
        {
            for(int i=1;i<=n;i++) g[i].clear();
            for(int i=0;i<n-1;i++)
            {
    
                cin>>a>>b>>c;
                g[a].push_back((node){b,c});
                g[b].push_back((node){a,c});
            }
    
            fill(vis,vis+n+1,false);
            st=dfs(1,0).p;
            fill(vis,vis+n+1,false);
            en=dfs(st,0).p;
            fill(dis,dis+n+1,0);
            fill(vis,vis+n+1,false);
            bfs(st);
            fill(vis,vis+n+1,false);
            bfs(en);
            LL ans=0;
            for(int i=1;i<=n;i++)
            {
                if(i==st) continue;
                ans+=dis[i];
            }
            cout<<ans<<endl;
        }
    
        return 0;
    }

    1268

    水题

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <queue>
    #define LL long long int
    using namespace std;
    
    int main()
    {
        cin.sync_with_stdio(false);
        LL a,b;
        while(cin>>a>>b)
        {
            LL x=__gcd(a,b);
            if(x==0) x=min(a,b);
            LL y=2*a*b;
            LL fix=__gcd(x,y);
            x/=fix,y/=fix;
            cout<<x<<'/'<<y<<endl;
        }
    
        return 0;
    }
  • 相关阅读:
    2015年个人记录
    Win10如何新建用户怎么添加新账户
    快速搭建一个本地的FTP服务器
    天气接口
    一张图搞定OAuth2.0
    PHP TS 和 NTS 版本选择
    如何在 Laravel 中使用 SMTP 发送邮件(适用于 163、QQ、Gmail 等)
    Npm vs Yarn 之备忘详单
    浅谈CSRF
    值得看的cookie详解
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/6918585.html
Copyright © 2020-2023  润新知