Educational Codeforces Round 124 (Rated for Div. 2)

本文介绍了Codeforces Round 124中的四道算法题目,包括签到题A.Playoff的解题思路,即2的n次方减一;B.ProveHimWrong通过公式推导得出解法;C.Fault-tolerantNetwork通过调整网络连接优化问题;D.NearestExcludedPoints利用多源BFS寻找最近点。文章详细分析了每道题目的解决方案,并给出了相应的C++代码实现。

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

Dashboard - Educational Codeforces Round 124 (Rated for Div. 2) - Codeforceshttps://codeforces.com/contest/1651

A. Playoff

签到题,第一轮以后剩下的都是奇数,奇数又取最大,答案就是2的n次方-1

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
 
const int maxn = 0;
const int mod = 1e7+9;
 
int main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        long long ans = pow(2,n)-1;
        cout<<ans<<endl;
    }
}

B. Prove Him Wrong

公式推导一下,如果YES,那么必然是x1+x2>=2(x2-x1),也就是3x1>=x2,能尽可能让范围在数据内的情况是1 3 9....打个表n<20的时候最后的数在1e9以内

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
 
const int maxn = 0;
const int mod = 1e7+9;
 
int main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        if(n>=20)
            cout<<"NO"<<endl;
        else{
            cout<<"YES"<<endl;
            int a = 1;
            for(int i = 1;i<=n;i++) {
                cout << a << " ";
                a *= 3;
            }
            cout<<endl;
        }
    }
}

C. Fault-tolerant Network

让首尾的度都变成2就可以了,由此推出七种情况(具体看代码吧)

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'

const int maxn = 2e5+10;
const int mod = 1e7+9;
int a[maxn] = {};
int b[maxn] = {};

int main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i = 1;i<=n;i++)
            cin>>a[i];
        for(int i = 1;i<=n;i++)
            cin>>b[i];
        long long ad1 = 1e9+10,ad2 = 1e9+10; //首尾到其他点的距离
        long long bd1 = 1e9+10,bd2 = 1e9+10; //首尾到其他点的距离
        long long abh = -1,abw = -1; //首首和尾尾
        long long abhw = -1,abwh = -1;//首尾和尾首
        abh = abs(a[1]-b[1]);
        abw = abs(a[n]-b[n]);
        abhw = abs(a[1]-b[n]);
        abwh = abs(b[1]-a[n]);
        for(int i = 1;i<=n;i++){
            long long d = abs(a[1]-b[i]);
            ad1 = min(ad1,d); //首到其他
            d = abs(a[n]-b[i]);
            ad2 = min(ad2,d);
        }
        for(int i = 1;i<=n;i++){
            long long d = abs(b[1]-a[i]);
            bd1 = min(bd1,d);
            d = abs(b[n]-a[i]);
            bd2 = min(bd2,d);
        }
        // cout<<ad1<<" "<<ad2<<" "<<bd1<<" "<<bd2<<" "<<abh<<" "<<abw<<" "<<abhw<<" "<<abwh<<endl;
        long long ans = min(abhw+abwh,abh+abw);
        ans = min(ans,abh+ad2+bd2);  //首首连
        ans = min(ans,abw+ad1+bd1);
        ans = min(ans,abhw+ad2+bd1);
        ans = min(ans,abwh+ad1+bd2);
        ans = min(ans,ad1+ad2+bd1+bd2);
        cout<<ans<<endl;
    }
}

D. Nearest Excluded Points

多源bfs,目的就是减少单点bfs的反复搜索,由贪心思路可知,两种情况,一种是身边有空的,那么答案就是空的,一种是身边没有空的,那么必然它的答案是身边的某一非空点的答案,再使用队列保证一旦找到就是最近距离之一即可。

#include <bits/stdc++.h>

#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn = 2e5+10;
pair<int,int>p[maxn];
map<pair<int,int>,pair<int,int>>ans;
set<pair<int,int>>vis;
queue<pair<int,int>>q;
pair<int,int>now;
pair<int,int>nex;
int dx[] = {0,0,0,1,-1};
int dy[] = {0,1,-1,0,0};

void bfs(){
    while(!q.empty()){
        now = q.front();
        q.pop();
        for(int i = 1;i<=4;i++){
            nex = {now.first+dx[i],now.second+dy[i]};
            if(vis.count(nex)&&!ans.count(nex)){ //被围死的点的答案和被围着的某个点一样
                ans[nex] = ans[now];
                q.push(nex);
            }
        }
    }
}

int main() {
    int n;
    cin>>n;
    for(int i = 1;i<=n;i++)
        cin >> p[i].first >> p[i].second;
    for(int i = 1;i<=n;i++)
        vis.insert(p[i]);
    /*for(int i = 1;i<=n;i++)
        cout<<p[i].first<<" "<<p[i].second<<endl;*/
    for(int i = 1;i<=n;i++){
        for(int j = 1;j<=4;j++) {
            now = {p[i].first + dx[j], p[i].second + dy[j]};
            if(!vis.count(now)) {
                ans[p[i]] = now;
                q.push(p[i]);
                break;
            }
        }
    }
    bfs();
    for(int i = 1;i<=n;i++)
        cout<<ans[p[i]].first<<" "<<ans[p[i]].second<<endl;
}

加油

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值