CCPC2017湘潭 1263 1264 1267 1268

Posted Luke_Ye

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

 

以上是关于CCPC2017湘潭 1263 1264 1267 1268的主要内容,如果未能解决你的问题,请参考以下文章

[CCPC2017]湘潭邀请赛

2021CCPC湘潭邀请赛复盘

2021CCPC湘潭邀请赛复盘

2021CCPC湘潭全国邀请赛题解

2021CCPC湘潭全国邀请赛题解

2021CCPC湘潭全国邀请赛题解