Codeforces 923 D. Picking Strings

http://codeforces.com/contest/923/problem/D

 

题意:

A-->BC , B-->AC , C-->AB , AAA-->empty

问指定串S是否能变成目标串T

 

发现1:B与C等价

B-->AC-->AAB-->AAAC-->C

C-->AB-->AAC-->AAAB-->B

发现2:B前面的A可以消去

AB-->AAC-->AAAB-->A

新的变换:

A-->BB , B-->AB , AB-->A , AAA-->empty

所以:

结论1:B之前可以增删任意个A

结论2:在A的位置可以变成任意偶数个B

结合结论1和结论2,现在只剩下末尾的A待解决

末尾的A是无法增加的,所以只能考虑把S串末尾多余的A删去

 

综上所述,本题解法:

1、若S和T的 b的数量的奇偶性不同,则无解 

因为B的改动只能是偶数个

2、若T中b的数量<S中b的数量,则无解

因为b只能加不能减

3、若T末尾A的数量>S末尾A的数量,则无解

因为末尾的A只能减不能加

删去末尾相同数量的A

考虑末尾的A

4、若 决定 变化最后1个A-->BB,在满足排除上面三种无解的前提下,若S中末尾A的数量>T中末尾B的数量 且 S中B的数量<T中B的数量,则有解

5、若决定删去3个A,若S串末尾A的数量是3的倍数 且 不存在 删去末尾相同数量的A后 S串是空串 T串不是空串

 

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=100010;

int sa[maxn],sb[maxn],ta[maxn],tb[maxn];

int n,m;
char s[maxn],t[maxn];

int main()
{
    scanf("%s%s",s+1,t+1);
    n=strlen(s+1);m=strlen(t+1);
    for(int i=1;i<=n;i++)
    {
        if(s[i]=='A')sa[i]=sa[i-1]+1;
        sb[i]=sb[i-1]+(s[i]=='B'||s[i]=='C');
    }
    for(int i=1;i<=m;i++)
    {
        if(t[i]=='A')ta[i]=ta[i-1]+1;
        tb[i]=tb[i-1]+(t[i]=='B'||t[i]=='C');
    }
    int Q;
    scanf("%d",&Q);
    int l,r,Sa,Sb,Ta,Tb,lenS,lenT;
    while(Q--)
    {
        scanf("%d%d",&l,&r);
        Sa=min(r-l+1,sa[r]);
        Sb=sb[r]-sb[l-1];
        lenS=r-l+1;
        scanf("%d%d",&l,&r);
        Ta=min(r-l+1,ta[r]);
        Tb=tb[r]-tb[l-1];
        lenT=r-l+1;
        if(Tb<Sb||((Tb&1)!=(Sb&1))||Ta>Sa) printf("0");
        else if((Ta<Sa&&Tb>Sb)||(( Ta!=lenS || Ta==lenT) && (Sa-Ta)%3==0)) printf("1");
        else printf("0");
    }
    return 0;
}

 

posted @ 2018-03-17 16:35  TRTTG  阅读(267)  评论(0编辑  收藏  举报