Educational Codeforces Round 124 (Rated for Div. 2)(A-C)

本文介绍了三道编程竞赛题目及其解题思路。A题是关于比赛淘汰赛的逻辑,关键在于理解奇数编号选手始终获胜。B题要求保持数组元素间操作后的和不变,通过3的倍数构建数组。C题涉及网络连接问题,解决策略是确保任意一台电脑故障后网络仍连通。每排电脑首尾相连即可保证这一点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. Playoff

题意:

告诉你会执行2的n次方次比赛,参赛选手的标号也从1~2的n次方,两两pk,如果二者编号和是偶数,那么编号大的获胜进入下一轮,否则是奇数小的进入下一轮

思路:

不难发现,第一轮时每一组偏小的都会获胜也就是奇数会获胜,而进入到第二轮全是奇数,那么他们的和全是偶数,之后也是如此,因为偶数都被淘汰了,所以都会是出现奇数pk奇数的情况,所以输出最大的奇数即可,也就是2^n-1;
 

#include<bits/stdc++.h>

using namespace std;

int main()
{
    long long  n,i,j,t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        long long d1=1;
        for(i=0;i<n;i++) d1*=2;
        cout<<d1-1<<endl;
    }
    return 0;
}

B. Prove Him Wrong

题意:

给你一个数组长度为n的数组,要求你可以执行无数次操作,每次操作选择任意一对数ai和aj,要求使得ai和aj都等于|ai-aj|,并且要保证操作之后整个数组的和不会减小,求是否能够成,不能则输出no,能则输出你构成的数租

思路:

其实题目的要求就是要求2*|a_{i}-a_{j}|>=a_{i}+a_{j} 拆分一下就是a_{i}>=3*a_{j}

所以就从最小的1开始,不断乘3,看看能否在1e9以内构成这个数组,如果越界就输出no

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int n,i,j,t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        long long  d1=1,flag=0;
        vector<int >a;
        for(i=0;i<n;i++)
        {
            a.push_back(d1);
            if(d1>1e9) {
                flag=1;
            }
            d1*=3;
        }
        if(flag==1)
        {
            cout<<"NO"<<endl;
        }
        else
        {
            cout<<"YES"<<endl;
            for(auto x:a)
            {
                cout<<x<<" ";
            }
            cout<<endl;
        }
    }
    return 0;
}

C. Fault-tolerant Network

题意:

题意提出来就是给你两排电脑,每一排电脑默认相连,并且每台电脑会有它的权值,然后你去连边,连边的花费就是两台电脑的权值和,现在要求你花费最少的价格,使得假设任意一台电脑死机后,剩下的电脑还是能够连通。且每一排电脑相领的两台电脑已经默认相连就像这样:

思路:

首先要去思考,如何连接才能使得断开任意一点剩下的还能都在一个环里呢?不难发现,如果他们从头连到尾像这样,那么断开任意一个点,剩下的都还是能继续连通的。

当然如果是交叉,那也可以

那么这是我连完两条线的情况,其实到这里就应该要发现,只要我对于任意一排主机来说,只要我连到了第一个点和最后一个点,那么他们之间就永远不会断开,都能从一头走到另外一排

所以对于每一排来说我都需要连头和尾两个点,那么最多就需要连接四条线,直接暴力跑出来,距离头部a0,b0,尾部an,bn距离最短的点有哪些,就解决了四条线的情况

那么还有三条线的情况,如何完成三条线连接到四个首尾点呢?

那么假设我一条线能连接两个首尾点,剩下两条线再分别连剩下的不就行了吗?

首先是一条线连接头部的: 

当然连接还有连接尾部的,加起来就两种了

那么还有头和尾部先连的:

 直接连接a0和bn即也有两种情况

所以三条线的有四种情况,两条线的两种情况,四条线的一种情况,总共7种

#include<bits/stdc++.h>

using namespace std;

const int maxn=2e5+1000;

#define int long long
int a[maxn],b[maxn];
signed main()
{
    int n,i,j,t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(i=0;i<n;i++)
        {
            cin>>a[i];
        }
        for(i=0;i<n;i++)
        {
            cin>>b[i];
        }
        long long ans1=0,ans2=0,ans3=0,ans4=0,ans5=0,ans6=0,ans7=0;
        ans1=abs(a[0]-b[0])+abs(a[n-1]-b[n-1]);
        ans2=abs(a[n-1]-b[0])+abs(a[0]-b[n-1]);
        long long a0=0x3f3f3f3f,b0=0x3f3f3f3f,an=0x3f3f3f3f,bn=0x3f3f3f3f;
        for(i=0;i<n;i++)
        {
            a0=min(a0,abs(b[i]-a[0]));
            an=min(an,abs(b[i]-a[n-1]));
            b0=min(b0,abs(a[i]-b[0]));
            bn=min(bn,abs(a[i]-b[n-1]));
        }
        ans3=abs(a[0]-b[0])+bn+an;
        ans4=abs(a[n-1]-b[n-1])+a0+b0;
        ans5=abs(a[0]-b[n-1])+b0+an;
        ans6=abs(a[n-1]-b[0])+a0+bn;
        ans7=a0+b0+an+bn;
        cout<<min({ans1,ans2,ans3,ans4,ans5,ans6,ans7})<<endl;
    }
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值