版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Lfhase/article/details/79593369
题目链接:点击打开链接
题意:给定两个由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;
}