Picking Strings CodeForces - 948E 构造 思维题

题意:

根据A->BC B->AC C->AB AAA->EMPTY 的规则问S中的【a,b】是否可以转化为T中的【c,d】

其实已经很接近了 已经想到C就是B A可以变成偶数个B B可以在前面加任意数目的A 后来设计了一个错误的分类WA几次就没耐心去看题解 其实接下来只要分分类就行了

设S区间中末尾A的数目为n T中为m

S中B的数目为p T中为q

1.如果n小于m 则一定不可能 因为不存在一种规则可以凭空生成A并移动到后面

2.如果n等于m 

    2.1 如果p等于q 那可以

    2.2 如果p小于q 当且仅当q-p模2为0是可以 因为A可以在前端凭空产生 但只能分解成偶数个B

    2.3 如果p大于q 则不可以 因为B的数目是不可能减少的

3.如果n大于m

    3.1 如果p大于等于q 则不可以 因为减少A必然会产生B

    3.2 如果p小于q 则当且q-p模2为0时可以 因为可以分解后面的A来产生偶数个B

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <string>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

const int maxn = 2e5+7;
char S[maxn],T[maxn];
int Q,a,b,c,d;
int sumS[maxn],sumT[maxn];
int lastS[maxn],lastT[maxn];
int main()
{
    scanf(" %s %s %d",S,T,&Q);
    for(int i = 0; S[i]; ++i)
    {
        sumS[i+1] = sumS[i] + (S[i] == 'C' || S[i] == 'B');
        lastS[i+1] = lastS[i];
        if(S[i] == 'B' || S[i] == 'C')
            lastS[i+1] = i+1;
    }
    for(int i = 0; T[i]; ++i)
    {
        sumT[i+1] = sumT[i] + (T[i] == 'C' || T[i] == 'B');
        lastT[i+1] = lastT[i];
        if(T[i] == 'B' || T[i] == 'C')
            lastT[i+1] = i+1;
    }
    while(Q--)
    {
        scanf("%d%d%d%d",&a,&b,&c,&d);
        int delta = sumT[d]-sumS[b]+sumS[a-1]-sumT[c-1];
        int delta2 = b - max(a-1,lastS[b]) - (d - max(c-1,lastT[d]));
        if(delta < 0 || delta % 2 != 0 || delta2 < 0 || delta2 == 0 && !(sumS[b] - sumS[a-1]) && delta > 0)
        {
            putchar('0');
            continue;
        }
        if(delta2 == 0 || delta > 0 || delta2 % 3 == 0)
            putchar('1');
        else
            putchar('0');
    }
    return 0;
}

很后悔 再耐心一点也许就出了 不该那么着急就看题解 这种思想大概就是书上说的“构造”吧

猜你喜欢

转载自blog.csdn.net/weixin_39302444/article/details/80114719