AtCoder Regular Contest 166——A - Replace C or Swap AB

你获得两个由A,B,C组成的字符串X,Y,长度为N。

通过对X执行以下三种操作,让X变成Y。

1:选择X中的字符C替换为字符A。

2.选择X中的字符C替换为字符B。

3.选择X中的子字符串AB,替换为BA。

首先,由于AB可以变成BA,则当X串中只有A,B时A可以任意向后交换移动

ABB->BAB->BBA

其次,当Y串中有C时,A串对应位置一定也是C,而A不能与C交换,则C左右块是不互通的,即我们可以通过Y串中的字符C来将Y串分成若干份,分块比较。

那么,X串中的字符C怎么办呢,因为X串中A只能向后移动,不能向前,所以我们需要尽可能的将前面C变成A(这里有个问题,如果X中A的数目或者B的数目比Y串中还多,那么无论C怎么补充都是不能配对的) ,然后判断X串中A的位置都前于Y串中A的位置即可

#include<iostream>
#include<algorithm>
#include<math.h>
#include<vector>
#include<cstring>
#include<map>
#include<queue>

#define int long long 
#define fast ios::sync_with_stdio(false);cin.tie(0);

using namespace std;
bool check(vector<int>a, vector<int>b)
{
    for (int i = 0; i < a.size(); i++)
    {
        if (a[i] > b[i])
            return 1;
    }
    return 0;
}
void solve()
{
    int n;
    string a, b;
    cin >> n >> a >> b;
    a += "C";
    b += 'C';
    n++;
    int a1 = 0, b1 = 0;
    int a2 = 0, b2 = 0;
    bool flag = 1;
    string ax, bx;
    for (int i = 0; i < n; i++)
    {
        if (b[i] == 'C')
        {
            if (a1 > a2 || b1 > b2 || a[i] != 'C')//X串中的A,B数目要小于等于Y串中A,B的数目
            {
                flag = 0;
                break;
            }
            else
            {
                int c = a2 - a1;
                vector<int>aax, bbx;
                for (auto &t:ax)
                {
                    if(t=='C')
                    if (c)
                        c--, t = 'A';//尽可能的把靠前的C变成A
                    else
                        t = 'B';
                }

                
                for (int i = 0; i < ax.size(); i++)
                    if (ax[i] == 'A')
                        aax.push_back(i);

                for (int i = 0; i < bx.size(); i++)
                    if (bx[i] == 'A')
                        bbx.push_back(i);

                if (check(aax, bbx))//判断X,Y串中A的相对位置
                {
                    flag = 0;
                    break;
                }
            }
            a1 = b1 = a2 = b2 = 0;
        }
        else
        {
            a1 += a[i] == 'A';
            b1 += a[i] == 'B';
            a2 += b[i] == 'A';
            b2 += b[i] == 'B';
            bx.push_back(b[i]);
            ax.push_back(a[i]);
        }
    }

    if (flag)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
}

signed main()
{
    fast;
    int tt = 1;
    cin >> tt;
    while (tt--)
    {
        solve();
    }
}

这里其实一开始我考虑不足,没有比较每个A的相对位置,而是只比较了字串字典序的大小(因为以为每个字串都可以朝向字典序增大的方向移动,但每个A只能向后不能向前移动,不能保证每个排列都能到达,如:ABBA->BABA->BBAA但不能到达BAAB)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值