CF #470 div2 思维+贪心模拟

38 篇文章 0 订阅
6 篇文章 0 订阅

解题思路:

果然贪心是这个世界上最恶心的思想,BUG太多了,让人崩溃。一开始以为会很难,比较就100多人过,没想到啥算法都没有,都是我也错了好几发,主要是没考虑完整。根据那个转换格式,容易发现B和C其实是一样,那么就把三个字符的问题变成了2个。那么我们需要用到两个数组,一个是记前i个字符中B的个数(C已经都看成B了),一个是从i位置往前有多少个连续的A字符。

根据推算,可知,一个B可变出无限个前导A+后面一个B,一个A可以变出两个B

记Sa是S串区间右界往前连续A字符个数,Ta则是T串的;Sb表示S串区间出现B的个数,Tb则是T的。接下就是无法转换得几个条件:

1.Sb&&!Tb ,因为B是不可删除的,所以肯定不行了

2.当Sb==Tb==0时这是已经全是A了,那么要S串A要比T多,且两者之差是三的倍数才可以转换

3.Sb>Tb,和1道理是一样的

4.Tb和Sb之差要是偶数,因为若要增加S串B的个数,那么肯定是2个2个增加的。

5.sb==0&&sa==ta,举例:S:AAA,T:BAAA,没有多余的A去变B了

6.S:BAA,T:BAAA,由A不能变成两个A可得,sa<Ta时是不行得

7.S:BBAAAAA,T:BBAA注意这个是可以的,A可以消掉不需要变成B

#include<bits/stdc++.h>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const int mx = 1e5 + 100;
int n,m,Tlen,Slen,SendA[mx],TendA[mx];
char Ts[mx],str[mx],ans[mx];
int Tsum[mx],Ssum[mx];
int main()
{
    scanf("%s%s",str+1,Ts+1);
    Tlen = strlen(Ts+1);
    Slen = strlen(str+1);
    for(int i=1;i<=Slen;i++) if(str[i]=='C') str[i] = 'B';
    for(int i=1;i<=Tlen;i++) if(Ts[i]=='C') Ts[i] = 'B';
    for(int i=1;i<=Slen;i++){
        if(str[i]=='B') SendA[i] = 0,Ssum[i] = Ssum[i-1]+1;
        else SendA[i] = SendA[i-1]+1,Ssum[i] = Ssum[i-1];
    }
    for(int i=1;i<=Tlen;i++){
        if(Ts[i]=='B') TendA[i] = 0,Tsum[i] = Tsum[i-1]+1;
        else TendA[i] = TendA[i-1]+1,Tsum[i] = Tsum[i-1];
    }
    scanf("%d",&n);
    ans[n] = 0;
    int a,b,c,d;
    for(int i=0;i<n;i++){
        scanf("%d%d%d%d",&a,&b,&c,&d);
        int Sa = min(b-a+1,SendA[b]),Ta = min(d-c+1,TendA[d]);
        int Sb = Ssum[b] - Ssum[a-1],Tb = Tsum[d] - Tsum[c-1];
        if(Sb&&!Tb) ans[i] = '0';
        else if(Sb==Tb&&Sb==0){
            if(b-a<d-c||(b-a-d+c)%3) ans[i] = '0';
            else ans[i] = '1';
        }else if(Sb>Tb) ans[i] = '0';
        else if((Tb-Sb)%2) ans[i] = '0';
        else if(Sb==0&&Sa==Ta) ans[i] = '0';
        else if(Sa<Ta||(Tb==Sb&&Sa&&(Sa-Ta)%3)) ans[i] = '0';
        else ans[i] = '1';
    }
    puts(ans);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值