Codeforces Global Round 20 [B~D]

链接:contest link

B.I love AAAB

题目

如果一个字符串长度大于等于 \(2\) 且最后一个字符为 B ,其他字符都为 A ,那么称这个字符串是

给定一个初始为空串的字符串 \(s_1\) ,可以执行任意次以下操作:

  • \(s_1\) 的任意位置插入一个好的字符串

给定一个字符串 \(s_2\) ,判断能否通过操作使 \(s_1\) 变为 \(s_2\)

分析

容易发现好串的 A 个数大于等于 B 的个数,所以如果 \(s_2\) 可以由好串组成,对于它的任意子串 \(s_1[1\cdots i]\) 满足 A 个数大于等于 B 的个数,且 \(s_1\) 的最后一个字符一定为 B

代码

#include<bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--) {
        string s;
        int cnt = 0;
        cin >> s;
        bool fnd = false;
        for(int i = 0; i < (int)s.size(); i++) {
            if(s[i] == 'A')
                cnt++;
            else
                cnt--;
            if(cnt < 0) {
                cout << "NO" << endl;
                fnd = true;
                break;
            }
        }
        if(!fnd)
            cout << (s[s.size() - 1] == 'B' ? "YES" : "NO") << endl;
    }
    return 0;
}

C.Unequal Array

题目

给定一个长度为 \(n\) 的数组 \(a\) ,一个数组的 equality 定义为满足 \(a_i=a_{i+1}\)\(i\) 的个数,可以执行如下操作:

  • 选定两个整数 \(i,x\) 使 \(a_i=a_{i+1}=x\)

求使 \(a\)equality 小于等于 \(1\) 的最小操作数

分析

\(l\) 是满足 \(a_i=a_{i-1}\) 的最小的 \(i\)\(r\) 是最大的 \(i\) ,可以发现如果 \(r-l\not= 1\) 那么 \(a\)equality 大于等于 \(2\) ,在执行操作 \(l,l+1,\cdots,r-3,r-2\)equality 变为 \(1\) ,所以最小操作数为 \(r-1-l\) 。如果 \(r-l=1\) ,那么最小操作数为 \(1\)

代码

#include<bits/stdc++.h>
using namespace std;

int a[200000 + 5];

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t;
    cin >> t;
    while(t--) {
        int n, st = -1, en = -1;
        cin >> n;
        for(int i = 1; i <= n; i++)
            cin >> a[i];
        for(int i = 2; i <= n; i++) {
            if(a[i] == a[i - 1]) {
                st = i;
                break;
            }
        }
        for(int i = n; i >= 2; i--) {
            if(a[i] == a[i - 1]) {
                en = i - 1;
                break;
            }
        }
        if(st == -1 || en < st)
            cout << 0 << endl;
        else
            cout << (en - st == 0 ? 1 : en - st) << endl;
    }
    return 0;
}

D.Cyclic Rotation

题目

给定一个长度为 \(n\) 的数组 \(a\) ,如果 \(a_l=a_r\) ,可以执行操作 \(a[l\cdots r]=\{a_{l+1},a_{l+2},\cdots,a_r,a_l\}\)

给定另一个数组 \(b\) ,判断 \(a\) 能否经过多次操作变成 \(b\)

分析

考虑反向操作,即对于 \(b\) 中相邻的两个元素 \(b_{i-1},b_i\) 我们可以把 \(b_i\) 放到 \(i-1\) 前的任意位置

用双指针,若现在有 \(a_l,b_r\) 要使 \(a_l\) 变为 \(b_r\)

\(a_l=b_r\) 那么 \(l+1,r+1\)

否则我们希望移动 \(l,r\) 中的一个,如果两者都无法移动,则无法匹配输出 NO

用一个 map<int, int> cnt 来记录匹配不成功的 \(a_l\) ,如果 \(b_{r-1}=b_r\) 那么可以消去一个 \(a_l\) ,如果不可以,那么把 \(a_l\) 加入 cnt ,记为匹配不成功,等待后面的 \(b_r\) 消去

代码

#include<bits/stdc++.h>
using namespace std;

const int MAX_N = 200000 + 5;
int a[MAX_N], b[MAX_N];

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    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];
        map<int, int> cnt;
        int l = 1, r = 1;
        bool flag = true;
        while(r <= n) {
            if(l <= n && a[l] == b[r]) {
                l++;
                r++;
            } else {
                if(cnt[b[r]] && b[r] == b[r - 1]) {
                    cnt[b[r]]--;
                    r++;
                } else if(l <= n) {
                    cnt[a[l]]++;
                    l++;
                } else {
                    flag = false;
                    break;
                }
            }
        }
        cout << (flag ? "YES" : "NO") << endl;
    }
    return 0;
}
posted @ 2022-04-24 20:03  f(k(t))  阅读(67)  评论(0编辑  收藏  举报