习题:Picking Strings(分析)
题目
思路
我们考虑从这些条件能推出什么来
\(B\rightarrow AC \rightarrow AAB \rightarrow AAAC \rightarrow C\)
\(C\rightarrow AB \rightarrow AC \rightarrow AAB\rightarrow AAC\rightarrow AAAB \rightarrow B\)
\(A\rightarrow BC\rightarrow BB\rightarrow CC\)
也就是说B和C是等价的
再者B前面有多少个A是无所谓的
\(B\rightarrow AB\rightarrow BBB\)
\(A\rightarrow BB\rightarrow BBBB\rightarrow B\)
也就是只要有A或者B,就能增加偶数个B
考虑无解的状况
记t串中B和C的数量减去s串中B和C的数量为dif1
我们注意到,操作都不可能在一个字符串之后增加A
所以判断字符串末尾A的数量
记s串末尾连续A的数量减去t串末尾连续A的数量为dif2
如果无解那么\(dif2<0\)
之后再分情况讨论
当\(dif2==0\)时
再\(dif1>0\)的情况下
那么我们只需要判断dif1是否为2的倍数就行了
注意判断空串的情况
当\(dif2>0\)时
那么当\(dif1>0\)时
判断奇偶即可
当\(dif1=0\)时
判断是否时3的倍数即可
代码
#include<iostream>
#include<cstring>
using namespace std;
int q;
char s[100005];
char t[100005];
int ss[100005];
int st[100005];
int ls[100005];
int lt[100005];
int lens;
int lent;
int a,b,c,d;
int main()
{
ios::sync_with_stdio(false);
cin>>s>>t>>q;
lens=strlen(s);
lent=strlen(t);
for(int i=lens;i>=1;i--)
s[i]=s[i-1];
for(int i=lent;i>=1;i--)
t[i]=t[i-1];
for(int i=1;i<=lens;i++)
{
ss[i]=ss[i-1];
ls[i]=ls[i-1];
if(s[i]=='B'||s[i]=='C')
{
ls[i]=i;
ss[i]++;
}
}
for(int i=1;i<=lent;i++)
{
st[i]=st[i-1];
lt[i]=lt[i-1];
if(t[i]=='B'||t[i]=='C')
{
lt[i]=i;
st[i]++;
}
}
for(int i=1;i<=q;i++)
{
cin>>a>>b>>c>>d;
int dif1=st[d]-st[c-1]-(ss[b]-ss[a-1]);
int dif2=b-max(a-1,ls[b])-(d-max(c-1,lt[d]));
if(dif1<0||dif2<0||dif1%2||(dif2==0&&ss[b]-ss[a-1]==0&&dif1>0))
cout<<"0";
else if(dif2==0||dif1>0||dif2%3==0)
cout<<"1";
else
cout<<"0";
}
return 0;
}