【CodeForces训练记录】Codeforces Round 998 (Div. 3)

训练情况

赛后反思

div3 给罚时拉满了,C题 \(k-a_i=a_i\) 的情况错掉怒罚五发,D题成结论猜猜乐了,E题看错题了,以为是边一致,实则联通就行,又被并查集背刺了

A题

斐波那契第三位可以从第一二位算出来,也可以从第四五位算出来,两个答案取大值即可

#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

void solve(){
    int a,b,d,e; cin>>a>>b>>d>>e;
    int ma = 0;
    int c = a + b;
    int ans = 0;
    if(c == a + b) ans++;
    if(d == b + c) ans++;
    if(e == c + d) ans++;
    ma = max(ans,ma);
    ans = 0;
    c = e - d;
    if(c == a + b) ans++;
    if(d == b + c) ans++;
    if(e == c + d) ans++;
    ma = max(ans,ma);
    cout<<ma<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

B题

我们可以找到 \(0 \sim n-1\) 对应的牛牛,这就是出牌顺序,接下来 \(n \sim nm-1\) 都按这个牛牛顺序出牌,如果有人没有这张牌就是无解情况,否则直接输出最开始的出牌顺序即可

#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

void solve(){
    int n,m; cin>>n>>m;
    vector<vector<int>> a(n + 1,vector<int>(m + 1));
    vector<int> pos(n*m*2);
    for(int i = 1;i<=n;i++){
        for(int j = 1;j<=m;j++){
            cin>>a[i][j];
            pos[a[i][j]] = i;
        }
    }
    vector<int> ans;
    for(int i = 0;i<n;i++) ans.push_back(pos[i]);
    bool flag = true;
    for(int i = n;i<n*m;i++){
        if(ans[(i-n)%n] != pos[i]) flag = false;
    }
    if(flag){
        for(int i = 0;i<n;i++) cout<<ans[i]<<" ";
    } else {
        cout<<-1;
    }
    cout<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

C题

这题实则博弈论没有用,就是找数列中 \(a+b=k\) 的对数,因为无论和等不等 \(k\) 的一对,博弈时 Alice 为了让得分最小选择不能和等 \(k\) 的数时,一定还有另一个数给 Bob 选择,所以不会对最终答案造成贡献,这里注意一下 \(k-a_i=a_i\) 的情况,还有数组越界的问题就行

#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

void solve(){
    int n,k; cin>>n>>k;
    vector<int> a(n + 1);
    int ma = 0;
    for(int i = 1;i<=n;i++){
        cin>>a[i];
        ma = max(ma,a[i]);
    }
    sort(a.begin() + 1,a.end(),greater<int>());
    vector<int> cnt(ma+1);
    for(int i = 1;i<=n;i++) cnt[a[i]]++;
    int ans = 0;
    for(int i = 1;i<=n;i++){
        if(k-a[i] >= 1 && k-a[i] <= ma){
            if(cnt[a[i]]&&cnt[k-a[i]]){
                ans++;
                cnt[a[i]]--;
                cnt[k-a[i]]--;
                if(cnt[a[i]]<0){
                    ans--;
                    cnt[a[i]]+=2;
                }
            }
        }
    }
    cout<<ans<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

D题

结论猜猜乐,因为两个数同减 min 不会改变相对大小关系,想要单调不减,前面的数就得小,盲猜一个全部操作再is_sorted判断单调给我猜对了

#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

void solve(){
    int n; cin>>n;
    vector<int> a(n + 1);
    for(int i = 1;i<=n;i++) cin>>a[i];
    for(int i = 2;i<=n;i++){
        int mi = min(a[i],a[i-1]);
        a[i-1]-=mi;
        a[i]-=mi;
    }
    // for(int i = 1;i<=n;i++) cout<<a[i]<<" ";
    // cout<<endl;
    if(is_sorted(a.begin() + 1,a.end())) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}

E题

两个图联通的节点情况要一致,所以我们使用两个并查集分别维护 \(F\) 图和 \(G\) 图的联通块,先维护 \(G\) 图联通,按 \(G\) 图的联通情况去判断 \(F\) 图的联通情况,如果不一致则答案加一,一致则合并 \(G\) 图,然后按 \(F\) 图的联通情况去判断 \(G\) 图的联通情况,如果不一致则答案加一再合并 \(F\) 图。

#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

const int N = 2e5 + 3;

int fa1[N],fa2[N];

int Find1(int x){
    if(fa1[x] == x) return x;
    return fa1[x] = Find1(fa1[x]);
}

int Find2(int x){
    if(fa2[x] == x) return x;
    return fa2[x] = Find2(fa2[x]);
}

void Union1(int x,int y){
    x = Find1(x); y = Find1(y);
    if(x == y) return;
    fa1[y] = x;
}

void Union2(int x,int y){
    x = Find2(x); y = Find2(y);
    if(x == y) return;
    fa2[y] = x;
}

void solve(){
    int n,m,k; cin>>n>>m>>k;
    for(int i = 1;i<=n;i++) fa1[i] = i,fa2[i] = i;
    vector<int> u1(m + 1),v1(m + 1),u2(k + 1),v2(k + 1);
    for(int i = 1;i<=m;i++){
        cin>>u1[i]>>v1[i];
    }
    for(int i = 1;i<=k;i++){
        cin>>u2[i]>>v2[i];
        Union2(u2[i],v2[i]);
    }
    int ans = 0;
    for(int i = 1;i<=m;i++){
        if(Find2(u1[i]) != Find2(v1[i])){
            ans++;
        } else {
            Union1(u1[i],v1[i]);
        }
    }
    for(int i = 1;i<=k;i++){
        if(Find1(u2[i]) != Find1(v2[i])){
            Union1(u2[i],v2[i]);
            ans++;
        }
    }
    cout<<ans<<endl;
}

signed main(){
    int T; cin>>T; while(T--)
    solve();
    return 0;
}
posted @   MNNUACM_2024ZY  阅读(97)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示