Codeforces Round #738 (Div. 2)

Codeforces Round #738 (Div. 2)

跳转链接

A. Mocha and Math

题目大意

有一个长度为\(n\)的数组 可以进行无数次下面的操作,问操作后数组中的最大值的最小值是多少
- 操作为:选两个位置\([l,r]\) 如果数组中从\(l\)\(r\)中每个元素\(a_{l+i}\)变为 \(a_{l+i}\)&\(a_{r-i}\)

思路

&操作是对于每一位上的数字,如果有一个\(0\)则当前位置上就为\(0\)
因此我们可以知道 当某个数字某位变成\(0\)之后,我们可以把这个0转移到这个数组中的任意一位,
而且&操作不会使数字变大, 因此我们可以选取一个数字,让他对全部的数字进行一次&操作
则这个数字就是这个数组进行操作后变得的数组中的最大值,当我们用其他数字&这个数字之后数字只会变得比它更小

AC_CODE

#include <iostream>
#include <vector>
 
using namespace std;
 
int main() {
    int T; cin >> T;
    while(T --) {
        int n; scanf("%d", &n);
        vector<int> a(n);
        for(int &x:a) cin >> x;
        for(int i = 1; i < n; i ++ ) {
            a[0] &= a[i];
        }
        cout << a[0] << endl;
    }
}

B. Mocha and Red and Blue

题目大意

定义一个字符串的不友好度为这个字符串中一共存在多少个位置连续两个字符相同
例如"BRRRBBR"的不友好度为3 出现了一次 "BB" 两次 "RR"
给定一个字符串 只包含B R ?
让我们把?变为 B or R 使得字符串的不友好度最低

思路

我们可以让?只受它前面的字符影响 与它前面的字符不同即可
首先需要特判一下长度为1的时候
当第一个字符为?的时候我们需要特判一下是否整个字符串全
都是? 这种情况我们间隔输出即可
当第一个字符为?且不是全部都是的时候,我们需要找到第一个
不是的字符的位置,如果它的下标和第一个字符的下标奇偶性相同
我们就把它赋值给第一个字符,否则就把另一个字符赋值给第一个字符
特判完第一个字符是?之后,我们只需要保持每个与它前面的字符
不相同即可

AC_CODE

#include <bits/stdc++.h>
#define x first    
#define y second    
#define pb push_back
#define mk make_pair
#define fi(a) fixed<<setprecision(a) 
#define debug(x) cout<<#x" ----> "<<x<<endl
#define rep(i, b, s) for(int i = (b); i <= (s); ++i)
#define pre(i, b, s) for(int i = (b); i >= (s); --i)
 
//#define int long long 
#define endl '\n' 
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
#define all(v) (v).begin(),(v).end()
 
using namespace std;
 
typedef pair<int, int> PII ;
typedef pair<double, double> PDD ;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-10;
const double pi = acos(-1.0);
   
int lowbit(int x){return x&-x;} 
LL gcd(LL a, LL b) {return b ? gcd(b, a%b) : a;}
LL lcm(LL a, LL b) {return a / gcd(a, b) * b;}
LL ksm(LL a, LL b) {if (b == 0) return 1; LL ns = ksm(a, b >> 1); ns = ns * ns % mod; if (b & 1) ns = ns * a % mod; return ns;}
 
template < typename T >
inline void read(T &x)
{
    x = 0; bool f = 0; char ch = getchar();
    while(!isdigit(ch)){f ^= !(ch ^ 45);ch=getchar();}
    while(isdigit(ch)) x= (x<<1)+(x<<3)+(ch&15),ch=getchar();
    x = f ? -x : x;
}
 
void solve() {
    int n; read(n);
    string x; cin >> x;
    if(n == 1) { // 特判长度为1
        if(x[0] != '?') cout << x << endl;
        else cout << "B\n";
        return;
    }
    bool flag = false;
    for(auto c : x) { // 判断是否全部为 ?
        if(c != '?') {
            flag = true;
            break;
        }
    }
    if(!flag) {
        for(int i = 0; i < n; i ++) {
            if(i & 1) putchar('B');
            else putchar('R');
        }
        puts(""); // 记得不要忘记换行
        return;
    }
    
    rep(i, 0, n - 1) {
        if(x[i] == '?') { 
            if(!i) {// 如果第一个字符为? 我们就找到第一个不是 ? 的位置 对第一个进行赋值
                if(x[i + 1] != '?') x[i] = (x[i + 1] == 'B' ? 'R' : 'B'); 
                else {
                    int j = i;
                    while(x[j] == '?' ) j ++;
                    if(j & 1) x[i] = (x[j] == 'B' ? 'R' : 'B');
                    else x[i] = x[j];
                }
            }
            else {
                x[i] = (x[i - 1] == 'B' ? 'R' : 'B');
            }
        }
    }
    cout << x << endl;
}
 
signed main() 
{
    int T = 1;cin >> T;
    while(T -- ) solve();
    return 0;
}

C - Mocha and Hiking

分析

根据题意呢,一共有四种可行路径,因此我们只需要判断这四种方法即可
第一种 n+1 - 1 - 2 ... n-1 - n
第二种 1 - 2 ... n-1 - n - n+1
第三种 1 - 2 - ... - x - n+1 - x+1 - ... - n
第四种 x+1 - ... - n - n+1 - 1 - 2 - ... - x

AC_CODE

#include <bits/stdc++.h>
#define x first    
#define y second    
#define pb push_back
#define mk make_pair
#define fi(a) fixed<<setprecision(a) 
#define debug(x) cout<<#x" ----> "<<x<<endl
#define rep(i, b, s) for(int i = (b); i <= (s); ++i)
#define pre(i, b, s) for(int i = (b); i >= (s); --i)

//#define int long long 
#define endl '\n' 
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
#define all(v) (v).begin(),(v).end()

using namespace std;
 
typedef pair<int, int> PII ;
typedef pair<double, double> PDD ;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-10;
const double pi = acos(-1.0);
   
int lowbit(int x){return x&-x;} 
LL gcd(LL a, LL b) {return b ? gcd(b, a%b) : a;}
LL lcm(LL a, LL b) {return a / gcd(a, b) * b;}
LL ksm(LL a, LL b) {if (b == 0) return 1; LL ns = ksm(a, b >> 1); ns = ns * ns % mod; if (b & 1) ns = ns * a % mod; return ns;}
 
template < typename T >
inline void read(T &x)
{
    x = 0; bool f = 0; char ch = getchar();
    while(!isdigit(ch)){f ^= !(ch ^ 45);ch=getchar();}
    while(isdigit(ch)) x= (x<<1)+(x<<3)+(ch&15),ch=getchar();
    x = f ? -x : x;
}
 
void solve() {
    int n, x; read(n);
    vector<bool> a(n), b(n);
    for(int i = 1; i <= n; i ++ ) {
        read(x);
        if(x) a[i] = 1; // n + 1 -- i
             // i --- n + 1
    }
    
    if(a[1]) {
        printf("%d ", n + 1);
        rep(i, 1, n) printf("%d ", i);
        puts("");
        return;
    }
    else if(!a[n]) {
        rep(i, 1, n) printf("%d ", i);
        printf("%d\n", n + 1);
        return;
    } 
    else {
        for(int i = 1; i < n; i ++ ) {
            if(!a[i] && a[i + 1]) {
                // puts("FUCK");
                for(int j = 1; j <= i; j ++ ) printf("%d ", j);
                printf("%d ", n + 1);
                for(int j = i + 1; j <= n; j ++ ) printf("%d ", j);
                puts("");
                return;
            }
            else if(a[i] && !a[i + 1] ){
                // puts("FUCKKK");
                for(int j = i + 1; j <= n; j ++ ) printf("%d ", j);
                printf("%d ", n + 1);
                for(int j = 1; j <= i; j ++ ) printf("%d ", j);
                puts("");
                return;
            }
        }



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

D1 - Mocha and Diana (Easy Version)

题意

给你两棵树 以及 两棵树上已经连接好的边
定义一个操作为给两棵树上均不连通的两个点加一条边,另一个树
也会将这两个点加上一个边
询问最多能进行多少次上述操作.

分析

我们可以用一个并查集维护一颗树上所有的连通块,同处于一个连通块内的
两个点是不可以加一条边的,可以加边的两个点需要满足在两个树中均不在
同一个连通块内
我们可以暴力循环每个点对 满足上述条件就将加边

AC_CODE

#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back

using namespace std;

typedef pair<int, int> PII;
const int N = 1010;
int p[2][N];
int find(int id, int x) {
    if(p[id][x] != x) p[id][x] = find(id, p[id][x]);
    return p[id][x];
}
int main() {
    int n, m1, m2;
    scanf("%d%d%d", &n, &m1, &m2);
    for(int i = 1; i <= n; i ++ ) p[0][i] = i, p[1][i] = i;
    while(m1 --) {
        int u, v;
        scanf("%d%d", &u, &v);
        int pu = find(0, u), pv = find(0, v);
        if(pu != pv) {
            p[0][pu] = pv;
        }
    }
    while(m2 --) {
        int u, v;
        scanf("%d%d", &u, &v);
        int pu = find(1, u), pv = find(1, v);
        if(pu != pv) {
            p[1][pu] = pv;
        }
    }
    vector<PII> ans;
    for(int i = 1; i <= n; i ++ ) {
        for(int j = i + 1; j <= n; j ++ ) {
            if(find(0, i) != find(0, j) && find(1, i) != find(1, j)) {
                ans.pb({i, j});
                p[0][find(0, i)] = find(0, j);
                p[1][find(1, i)] = find(1, j);
            }
        }
    }
    printf("%d\n", ans.size());
    for(PII p: ans) {
        printf("%d %d\n", p.x, p.y);
    }
    return 0;
}

posted @ 2021-08-16 10:46  ccz9729  阅读(156)  评论(0编辑  收藏  举报