codeforces #307 B. ZgukistringZ(枚举+计数)

来源:互联网 发布:河南省进出口数据 编辑:程序博客网 时间:2024/05/18 12:39

题目链接:

卖萌的链接

题目大意:

给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为子串不重叠且出现次数最多的串

题目分析:

其实就是对A,B,C进行计数,判断A中的各个字母的个数分别能分给几个B和几个C,枚举B的个数,计算C的个数,然后取最大值即可,记录去最大值情况下B出现的次数和C出现的次数然后先把B,C输出对应次数,然后把剩下的字符输出出去就好了。比较恶心的是,这道题竟然卡常数,真的在卡常数,所以要进行一个小的剪枝,也就是先求出B出现的最大次数,也就是A全部转成B的情况下B的个数,优化效果出奇的好,但并不是证明优化效果,复杂度怎么算都是26*o(n)

代码如下:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#define MAX 100007int num1[50];int num2[50];int num3[50];int num[50];char s1[MAX];char s2[MAX];char s3[MAX];using namespace std;void scan ( char s[] ){    char ch;    ch = getchar ();    int i = 0;    while ( true )    {        if ( ch == ' ' || ch == '\r' || ch == '\n' ) break;        s[i++] = ch;        ch = getchar();    }    s[i] = 0;}void print ( char s[] ){    int i = 0;    while ( s[i] )        putchar ( s[i++] );}int main ( ){    //while ( true )    //{        scan ( s1 );        memset ( num1 , 0 , sizeof ( num1 ) );        memset ( num2 , 0 , sizeof ( num2 ) );        memset ( num3 , 0 , sizeof ( num3 ) );        //scanf ( "%s" , s2 );        scan ( s2 );        //scanf ( "%s" , s3 );        scan ( s3 );        int len = strlen(s1);        for ( int i = 0 ; i < len ; i++ )            num1[s1[i]-97]++;        len = strlen(s2);        for ( int i = 0 ; i < len ; i++ )            num2[s2[i]-97]++;        len = strlen(s3);        for ( int i = 0 ; i < len ; i++ )            num3[s3[i]-97]++;        int ans = 0;        int sum1 = MAX , sum2 = MAX;        for ( int i = 0 ; i < 26 ; i++ )            if ( num2[i] )                sum1 = min ( sum1 , num1[i]/num2[i] );        for ( int i = 0 ; i < 26 ; i++ )            if ( num3[i] )                sum2 = min ( sum2 , num1[i]/num3[i] );        int index = sum1;        sum1 = sum2 = 0;        for ( int i = 0 ; i <= index ; i++ )        {            bool flag = false;            for ( int j = 0 ; j < 26 ; j++ )            {                num[j] = num1[j] - num2[j]*i;                if ( num[j] < 0 )                {                    flag = true;                    break;                }            }            if ( flag ) continue;            int temp = MAX;            for ( int j = 0 ; j < 26 ; j++ )                if ( num3[j] )                    temp = min ( temp , num[j]/num3[j] );            if ( temp + i > ans )            {                ans = temp + i;                sum1 = i;                sum2 = temp;            }        }        if ( ans = 0 ) print(s1);        else         {            for ( int i = 0 ; i < sum1 ; i++ )                //printf ( "%s" , s2 );                print(s2);            for ( int i = 0 ; i < sum2 ; i++ )                //printf ( "%s" , s3 );                print(s3);            for ( int i = 0 ; i < 26 ; i++ )                num1[i] -= sum1*num2[i] + sum2*num3[i];            for ( int i = 0 ; i < 26 ; i++ )                while ( num1[i]-- )                    //printf ( "%c" , 'a'+i );                    putchar((char)('a'+i));            puts ("");        }    //}}


0 0
原创粉丝点击