Codeforces Round #470 D Picking Strings

題目鏈接:https://codeforces.com/contest/947/problem/D

題意:給定兩個由A、B、C三個字母組成的串S、T,以及一系列串上的操作,給出Q的詢問,詢問S[ a, b]可否經過一系列操作生成T[ c, d]。

思路:根據數據規模,必須要離線構建一些東西來解決該問題。

首先,觀察給出的操作,可以發現如下規律:

1. C和B可以相互轉化

2. B之前的A可以任意增添

3.  B只能增加,且B的每次增加都爲偶數

所以,不妨根據前後兩串中B的數量進行分類討論:

1. 若第一個串內B的數量大於第二串,則必然不行。

2. 若兩者相等,則判斷所有B之後A的數量,若前者的這樣的A的數量 - 後者 是3的倍數則可行,否則不可行。

3. 若前者小於後者,先判斷差是否爲偶數,若不是偶數則不可行。如果是偶數,則判斷所有B之後A的數量,若前者大於後者且差不爲0則必然可行,若兩者這樣的A的數量相等,且前者B的數量不爲0則可行,否則不可行。

剩下的工作即計算B的數量以及這樣的A的數量,看代碼即可。

AC代碼如下:

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>


using namespace std;

#define FSIO  ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a)   cout<<"DEBUG: "<<(a)<<endl;

const int MAXN = 100005;
const int MOD = 1e9+7;
const int INF = 1e9+7;

string S, T;
int cnts[MAXN];
int cntgs[MAXN];
int cntt[MAXN];
int cntgt[MAXN];
int Q;


int main()
{
    FSIO;
    cin>>S>>T;
    for(int i=0;i<S.length();++i)
        if(S[i]=='B'||S[i]=='C')   cnts[i+1]=cnts[i]+1;
        else    cnts[i+1]=cnts[i], cntgs[i+1] = cntgs[i]+1;
    for(int i=0;i<T.length();++i)
        if(T[i]=='B'||T[i]=='C')   cntt[i+1]=cntt[i]+1;
        else    cntt[i+1]=cntt[i], cntgt[i+1] = cntgt[i]+1;
    /*for(int i=1;i<=S.length();++i)   cout<<cnts[i]<<" ";
    cout<<endl;
    for(int i=1;i<=T.length();++i)   cout<<cntt[i]<<" ";
    cout<<endl;*/
    cin>>Q;
    int l1, l2, r1, r2;
    for(int i=1;i<=Q;++i)
    {
        cin>>l1>>r1>>l2>>r2;
        if((cnts[r1]-cnts[l1-1])>(cntt[r2]-cntt[l2-1])) cout<<0;
        else if((cnts[r1]-cnts[l1-1])==(cntt[r2]-cntt[l2-1]))
        {
            int tmp = min(cntgs[r1], r1-l1+1);
            int tmp2 = min(cntgt[r2], r2-l2+1);
            if(tmp>=tmp2&&(tmp-tmp2)%3==0) cout<<1;
            else    cout<<0;
        }
        else
        {
            int cntb = cntt[r2]-cntt[l2-1]-(cnts[r1]-cnts[l1-1]);
            if(cntb%2==0)
            {
                int tmp = min(cntgs[r1], r1-l1+1);
                int tmp2 = min(cntgt[r2], r2-l2+1);
                if(tmp>tmp2||(tmp==tmp2&&(cnts[r1]-cnts[l1-1])))   cout<<1;
                else    cout<<0;
            }
            else    cout<<0;
        }
    }
    cout<<endl;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章