Codeforces Round #738 (Div. 2) A~D1题解

A. Mocha and Math

  • 题意
    给你一个 n n n元素的数组。你可以进行任意次操作选定区间 [ l , r ] [l,r] [l,r],使得 a [ l ] = a [ l ] & a [ r ] , . . . . a [ r ] = [ r ] & a [ l ] a[l] = a[l]\& a[r],....a[r] = [r] \&a[l] a[l]=a[l]&a[r],....a[r]=[r]&a[l]。问使得所有情况中序列的最大值最小为多少?

  • 解题思路
    由于可以进行任意次操作,而我们又得知 & \& &操作不会增大,所以我们必然可以让最大值变成所有数相 & \& &的值,这肯定是最小的,而这种操作刚好能符合我们这样做。故答案可得。

  • AC代码

/**
  *@filename:A_Mocha_and_Math
  *@author: pursuit
  *@created: 2021-08-15 22:36
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl

using namespace std;

typedef pair<int,int> pii;
typedef long long ll;
const int N = 100 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;

int t,n,a[N];
int minn;
void solve(){
    for(int i = 2; i <= n; ++ i){
        a[1] = a[1] & a[i];
    }
    cout << a[1] << endl;
}
int main(){	
    scanf("%d", &t);
    while(t -- ){
        scanf("%d", &n);
        for(int i = 1; i <= n; ++ i){
            scanf("%d", &a[i]);
        }
        solve();
    }
    return 0;
}

B. Mocha and Red and Blue

  • 题意
    给你一个包含B,R,?的字符串,其中你需要将?替换成B,R,请你构造出使得连续B和连续R最小的字符串。

  • 解题思路
    贪心的去看这道题,我们即从已有的字符B,R出发,即如果存在一个字符是B,R,我们就可以贪心的构造其相邻的,只要让它们不连续则可局部最优,从而构成全局最优。

  • AC代码

/**
  *@filename:B_Mocha_and_Red_and_Blue
  *@author: pursuit
  *@created: 2021-08-15 22:49
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl

using namespace std;

typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;

int t,n;
string s;
void solve(){
    char pre = 'a';
    bool flag = false;
    while(true){
        bool flag1 = false,flag2 = false;
        for(int i = 0; i < n; ++ i){
            if(s[i] == 'B' || s[i] == 'R'){
                flag1 = true;
                if(i - 1 >= 0 && s[i - 1] == '?'){
                    if(s[i] == 'B')s[i - 1] = 'R';
                    else s[i - 1] = 'B';
                    flag2 = true;
                }
                if(i + 1 < n && s[i + 1] == '?'){
                    if(s[i] == 'R')s[i + 1] = 'B';
                    else s[i + 1] = 'R';
                    flag2 = true;
                }
                //cout << s[i] << " ";
            }
        }
        if(!flag1){
            s[0] = 'B';
        }
        if(flag1 && !flag2){
            break;
        }
    }
    cout << s << endl;
}
int main(){	
    cin >> t;
    while(t -- ){
        cin >> n >> s;
        solve();
    }
    return 0;
}

C. Mocha and Hiking

  • 题意
    给你 n + 1 n+1 n+1个顶点的图,其中 1 1 1~ n n n i i i i + 1 i+1 i+1有一条边,能从 i i i i + 1 i+1 i+1。同时有一个数组 a a a,其中 a i = 0 a_i=0 ai=0则代表能从 i i i n + 1 n+1 n+1,若 a i = 1 a_i=1 ai=1则代表能从 n + 1 n+1 n+1 i i i。问每个村庄只走一次,走完所有村庄的方案。

  • 解题思路
    对于 1 1 1~ n n n,由于我们只能从 i i i i + 1 i+1 i+1,所以我们的方案必然是从 i i i跳到 n + 1 n+1 n+1再从 n + 1 n+1 n+1回到 i i i,这样就必须满足 a i = 0 , a i + 1 = 1 a_i=0,a_{i+1}=1 ai=0,ai+1=1。特殊的情况即我们直接从 n + 1 n+1 n+1出发,或者最后到达 n + 1 n+1 n+1,这需要满足 a [ n ] = 0 a[n]=0 a[n]=0或者 a [ 0 ] = 1 a[0]=1 a[0]=1,这样才可满足构造条件。

  • AC代码

/**
  *@filename:C_Mocha_and_Hiking
  *@author: pursuit
  *@created: 2021-08-15 23:25
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl

using namespace std;

typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;

int t,n,a[N];
void solve(){
    if(a[n] == 0){
        for(int i = 1; i <= n + 1; ++ i){
            printf("%d ", i);
        }
        puts("");
    }
    else if(a[1] == 1){
        printf("%d ", n + 1);
        for(int i = 1; i <= n; ++ i){
            printf("%d ", i);
        }
        puts("");
    }
    else{
        int idx = -1;
        for(int i = 1; i < n; ++ i){
            if(a[i] == 0 && a[i + 1] == 1){
                idx = i;
                break;
            }
        }
        if(idx == -1){
            puts("-1");
        }
        else{
            for(int i = 1; i <= n; ++ i){
                printf("%d ", i);
                if(idx == i){
                    printf("%d ", n + 1);
                }
            }
        }
    }
}
int main(){	
    scanf("%d", &t);
    while(t -- ){
        scanf("%d", &n);
        for(int i = 1; i <= n; ++ i){
            scanf("%d", &a[i]);
        }
        solve();
    }
    return 0;
}

D1. Mocha and Diana (Easy Version)

  • 题意
    给你两棵森林,可以为它们添加相同的边,需要使得它们还是森林能添加的最大边数。

  • 解题思路
    树即是森林,说明白了这道题其实就是并查集裸题,我们只需要不出现环即可。所以我们利用两个并查集维护这两颗森林,先处理边,对于 D 1 D1 D1我们暴力处理所有边然后判断是否可以添加即可。

  • AC代码

/**
  *@filename:D1_Mocha_and_Diana_Easy_Version_
  *@author: pursuit
  *@created: 2021-08-15 23:44
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl

using namespace std;

typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;

int n,m[2],father[2][N];
int find(int op,int x){
    return father[op][x] ^ x ? father[op][x] = find(op,father[op][x]) : x;
}
void solve(){
    int res = 0;
    vector<pii> ans;
    int x,y,z,w;
    for(int i = 1; i <= n; ++ i){
        for(int j = 1; j <= n; ++ j){
            x = find(0,i),y = find(0,j),z = find(1,i),w = find(1,j);
            if((x ^ y) && (z ^ w)){
                father[0][x] = y;
                father[1][z] = w;
                res ++;
                ans.push_back({i,j});
            }
        }
    }
    printf("%d\n", res);
    for(int i = 0; i < res; ++ i){
        printf("%d %d\n", ans[i].first, ans[i].second);
    }
}
int main(){	
    scanf("%d%d%d", &n, &m[0], &m[1]);
    for(int i = 1; i <= n; ++ i){
        father[0][i] = father[1][i] = i;
    }
    int u,v,fu,fv;
    for(int i = 1; i <= m[0]; ++ i){
        scanf("%d%d", &u, &v);
        fu = find(0,u),fv = find(0,v);
        if(fu ^ fv){
            father[0][fu] = father[0][fv];
        }
    }
    for(int i = 1; i <= m[1]; ++ i){
        scanf("%d%d", &u, &v);
        fu = find(1,u),fv = find(1,v);
        if(fu ^ fv){
            father[1][fu] = father[1][fv];
        }
    }
    solve();
    return 0;
}
posted @ 2022-03-26 16:48  unique_pursuit  阅读(38)  评论(0)    收藏  举报