Codeforces 551B: Zguki stringZ

题意:给你3个字符串a,b,c(均由小写英文字母构成),要求移动字符串a里面字母的位置,使得a字符串里b,c出现的总次数最多,并且重叠部分不算在内。

思路:先枚举其中一个字串(b或c)在a中出现的次数,然后计算对应情况下,另一字串出现的次数,保留最大的那个总次数和即可。

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
int len1, len2, len3;
char a[N], b[N], c[N];
int h1[30],h2[30], h3[30];
int cnt, cnt2, cnt3;

bool cmp(int a, int b)
{
	return a > b;
}

int main()
{
	while(~scanf("%s%s%s", &a, &b, &c))
	{
		getchar();
		len1 = strlen(a);
		len2 = strlen(b);
		len3 = strlen(c);
		for(int i = 0; i < len1; i++)
		{
			h1[a[i]-'a'] ++;
		}
		for(int i = 0; i < len2; i++)
		{
			h2[b[i]-'a'] ++;
		}
		for(int i = 0; i < len3; i++)
		{
			h3[c[i]-'a'] ++;
		}
		cnt = 0;  
       for(int i=1; ; i++)  
        {  
            int p = N;  
            for(int j = 0; j < 26; j++)  
            {  
                if(h1[j]-h2[j]*i<0)  
                {  
                    p=0;  
                    break;  
                }  
            }  
            if(!p) break;  
            int p2 = N;  
            for(int j = 0; j < 26; j++)  
            {  
                if(h3[j])  
                {  
                    p2 = min(p2, (h1[j] - h2[j] * i) / h3[j]);  
                }  
            }  
            if(i+p2>cnt)  
            {  
                cnt = i+p2;  
                cnt2 = i;  
                cnt3 = p2;  
            }  
        }  
        for(int i=1;; i++)  
        {  
            int p = N;  
            for(int j = 0; j < 26; j++)  
            {  
                if(h1[j]-h3[j] * i < 0)  
                {  
                    p=0;  
                    break;  
                }  
            }  
            if(!p) break;  
            int p2 = N;  
            for(int j = 0; j < 26; j++)  
            {  
                if(h2[j])  
                {  
                    p2 = min(p2, (h1[j] - h3[j] * i) / h2[j]);  
                }  
            }  
            if(i + p2 > cnt)  
            {  
                cnt = i+p2;  
                cnt3 = i;  
                cnt2 = p2;  
            }  
        }  
        for(int i = 0; i < cnt2; i++)  
            printf("%s", b);  
        for(int i = 0; i < cnt3; i++)  
            printf("%s", c);  
        for(int i = 0; i < 26; i++)  
        {  
            for(int j = 0; j < h1[i] - cnt2 * h2[i] - cnt3 * h3[i]; j++)  
                printf("%c",i+'a');  
        }  
        printf("\n");  
    }  
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值