• D. Linguistics (贪心+观察题目特性(数列特性))(CF 794 d2)


    D. Linguistics
    time limit per test1 second
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    Alina has discovered a weird language, which contains only 4 words: A, B, AB, BA. It also turned out that there are no spaces in this language: a sentence is written by just concatenating its words into a single string.
    
    Alina has found one such sentence s and she is curious: is it possible that it consists of precisely a words A, b words B, c words AB, and d words BA?
    
    In other words, determine, if it's possible to concatenate these a+b+c+d words in some order so that the resulting string is s. Each of the a+b+c+d words must be used exactly once in the concatenation, but you can choose the order in which they are concatenated.
    
    Input
    The first line of the input contains a single integer t (1≤t≤105) — the number of test cases. The description of the test cases follows.
    
    The first line of each test case contains four integers a, b, c, d (0≤a,b,c,d≤2105) — the number of times that words A, B, AB, BA respectively must be used in the sentence.
    
    The second line contains the string s (s consists only of the characters A and B, 1≤|s|≤2105, |s|=a+b+2c+2d)  — the sentence. Notice that the condition |s|=a+b+2c+2d (here |s| denotes the length of the string s) is equivalent to the fact that s is as long as the concatenation of the a+b+c+d words.
    
    The sum of the lengths of s over all test cases doesn't exceed 2⋅105.
    
    Output
    For each test case output YES if it is possible that the sentence s consists of precisely a words A, b words B, c words AB, and d words BA, and NO otherwise. You can output each letter in any case.
    
    Example
    inputCopy
    8
    1 0 0 0
    B
    0 0 1 0
    AB
    1 1 0 1
    ABAB
    1 0 1 1
    ABAAB
    1 1 2 2
    BAABBABBAA
    1 1 2 3
    ABABABBAABAB
    2 3 5 4
    AABAABBABAAABABBABBBABB
    1 3 3 10
    BBABABABABBBABABABABABABAABABA
    outputCopy
    NO
    YES
    YES
    YES
    YES
    YES
    NO
    YES
    Note
    In the first test case, the sentence s is B. Clearly, it can't consist of a single word A, so the answer is NO.
    
    In the second test case, the sentence s is AB, and it's possible that it consists of a single word AB, so the answer is YES.
    
    In the third test case, the sentence s is ABAB, and it's possible that it consists of one word A, one word B, and one word BA, as A+BA+B=ABAB.
    
    In the fourth test case, the sentence s is ABAAB, and it's possible that it consists of one word A, one word AB, and one word BA, as A+BA+AB=ABAAB.
    
    In the fifth test case, the sentence s is BAABBABBAA, and it's possible that it consists of one word A, one word B, two words AB, and two words BA, as BA+AB+B+AB+BA+A=BAABBABBAA.
    View problem

    思路:

    • 题目已经保证a+b+c+d=|s|
    • 首先判断 A,B 的个数能不能组成 A,B,AB,BA, 
    • 然后判断给定的序列 能不能找出 C 个AB 和 D BA
    • 于是重复数列不用看, 就看相邻不同的数列
    • 有 奇数,偶数个情况: 
    • 偶数 : ABABABAB, BABABABA, 发现如果去掉开头 和结尾, 就会分别变成对方 BABABA, ABABAB, (VAL-1)
    • 奇数  ABABABABA, BABABAB, 发现 任意去某个字符, 就可以形成 a个AB+b个BA (a+b=长度/2(向下取整))
    • 贪心的 让 AB的个数刚刚满足 c, 让BA的个数尽量大, 看能否符合条件不
    • 当然 对于偶数,就让他们填充各自位子,然后多退少补利用 奇数+偶数, 按照上面一个步骤贪心
    • 利用 偶数时 在贪心一下, 然长度长的先搞,因为每转化一次要付出 一个AB的代价,所以能用一个数列,就不用2个
    #include <bits/stdc++.h>
    using namespace std;
    #define ri register int
    #define  M 200005
    // 14:50
    template <class G> void read(G &x)
    {
        x=0;int f=0;char ch=getchar();
        while(ch<'0'||ch>'9'){f=ch=='-';ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x=f?-x:x;
        return ;
    }
     
     
    int t;
    string s;
    struct dian{
        int val;
        bool operator <(const dian t)const
        {
            return val>t.val;
        }
    }aa[M],bb[M],cc[M];
    int main(){
        
        cin>>t;
        while(t--)
        {
            int a,b,c,d;
            cin>>a>>b>>c>>d;
            cin>>s;
            int A=0,B=0;
            int n1=0,n2=0,n3=0;
            for(ri i=0;i<s.length();i++)
            {
                if(s[i]=='A') A++;
                else B++;
            }
            if(A!=a+d+c||B!=b+c+d)
            {
                printf("NO\n");
                continue;
            }
            int tmp=0;char cur;
            for(ri i=0;i<s.length();i++)
            {
                if(i==0)
                {
                    tmp=1;cur=s[i];
                }
                else
                {
                    if(s[i-1]!=s[i])
                    {
                        tmp++;cur=s[i];
                    }
                    else 
                    {
                        if(tmp<=1)
                        {
                            tmp=1;cur=s[i];
                            continue;
                         } 
                        if(tmp&1)
                        {
                            cc[++n3].val=tmp/2;
                        }
                        else
                        {
                            if(cur=='A')
                            {
                                bb[++n2].val=tmp/2;
                            }
                            if(cur=='B')
                            {
                                aa[++n1].val=tmp/2;
                            }
                        }
                        tmp=1;cur=s[i];
                    }
                }
            }
            if(tmp>1)
            {
                if(tmp&1)
                {
                    cc[++n3].val=tmp/2;
                }
                else
                {
                   if(cur=='A')
                    {
                    bb[++n2].val=tmp/2;
                    }
                    if(cur=='B')
                    {
                    aa[++n1].val=tmp/2;
                    }
                }
            }
            int tmpc=0,tmpd=0;
            for(ri i=1;i<=n1;i++)
            {
                tmpc+=aa[i].val;
            }
            for(ri i=1;i<=n2;i++)
            {
                tmpd+=bb[i].val;
            }
            if(tmpc<c)
            {
                for(ri i=1;i<=n3;i++)
                {
                    if(tmpc+cc[i].val<c)
                    {
                        tmpc+=cc[i].val;
                        cc[i].val=0;
                    }
                    else
                    {
                        cc[i].val-=(c-tmpc);
                        tmpc=c;
                        break;
                    }
                }
            }
            if(tmpc<c&&tmpd<=d)
            {
                printf("NO\n");
                continue;
            }
            if(tmpc<c)
            {    
                sort(bb+1,bb+1+n2);
                for(ri i=1;i<=n2;i++)
                {
                    if(tmpd-bb[i].val>=d)
                    {
                        tmpd-=bb[i].val;
                        tmpc+=bb[i].val-1;
                        if(tmpc>=c) break;
                    }
                    else
                    {
                        if(tmpd-d-1>=1) tmpc+=tmpd-d-1;
                        break;
                    }
                }
                if(tmpc<c) printf("NO\n");
                else printf("YES\n");
                continue;
            }
            for(ri i=1;i<=n3;i++)
            {
                tmpd+=cc[i].val;
            }
            if(tmpd<d)
            {
                sort(aa+1,aa+1+n1);
                for(ri i=1;i<=n1;i++)
                {
                    if(tmpc-aa[i].val>=c)
                    {
                        tmpc-=aa[i].val;
                        tmpd+=aa[i].val-1;
                        if(tmpd>=d) break;
                    }
                    else
                    {
                        if(tmpc-c-1>=1) tmpd+=tmpc-c-1;
                        break;
                    }
                }
                if(tmpd<d) 
                {
                  //cout<<A<<" "<<a+d+c<<endl;
                    printf("NO\n");continue;
                }
            }
            printf("YES\n");
        
        }
        return 0;
        
    }
    View Code

    本蒟蒻写的代码也太长了吧!!一点也不简洁!!!

  • 相关阅读:
    不舍
    java 笔记
    Javascript 行为委托
    JavaScript 函数调用的 this词法
    Javascript 闭包
    Javascript 原型链
    理解css的BFC
    多模态检索之CCA算法
    MySQL 基础概念、基础配置、密码破解
    Python的进程和线程
  • 原文地址:https://www.cnblogs.com/Lamboofhome/p/16347476.html
Copyright © 2020-2023  润新知