题意:给你a,b,c3个字符串,要求合理的调整a中的字符顺序,使其尽可能多的包含b,c;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a) memset(a,0,sizeof(a))
typedef long long ll;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const int big=50000;
ll max(int a,int b) {return a>b?a:b;};
ll min(int a,int b) {return a<b?a:b;};
char a[100005],b[100005],c[100005];
int numa[27],numb[27],numc[27];
int main()
{
    while(~scanf("%s",a))
    {
        scanf("%s",b);
        scanf("%s",c);
        MM(numa);MM(numb);MM(numc);

        for(int i=0;a[i]!='\0';i++)
            numa[a[i]-'a']++;
        for(int i=0;b[i]!='\0';i++)
            numb[b[i]-'a']++;
        for(int i=0;c[i]!='\0';i++)
            numc[c[i]-'a']++;
        int ans1=0,ans2=0,m=inf,n=0;
        for(int i=0;i<=25;i++)
        if(numb[i])  m=min(m,numa[i]/numb[i]);
        for(int i=0;i<=m;i++)
        {
            int temp=inf;
            for(int j=0;j<=25;j++)
            if(numc[j])    temp=min(temp,(numa[j]-i*numb[j])/numc[j]);
            if(temp+i>ans1+ans2)
            {
                ans1=i;
                ans2=temp;
            }
        }
        for(int i=0;i<ans1;i++) printf("%s",b);
        for(int i=0;i<ans2;i++) printf("%s",c);
        for(int i=0;i<=25;i++)
            {while(numa[i]-ans1*numb[i]-ans2*numc[i]>0)
              {printf("%c",i+'a');numa[i]--;};}
        printf("\n");
    }
    return 0;
}


分析:刚开始确实是想到了暴力,但是是分别枚举最先拿b和最先拿c两种情况的,所以代码比较复杂,所以就wa了


上面这个算法就是先求出拿b的话所能得到的最大的个数,那么最优解肯定就是在不拿b(0)和先满足b两种情况



之中了,接下来暴力一下就好;



下面是wa代码;



#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a) memset(a,0,sizeof(a))
typedef long long ll;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const int big=50000;
ll max(int a,int b) {return a>b?a:b;};
ll min(int a,int b) {return a<b?a:b;};
char a[100005],b[100005],c[100005];
char bb[100005],cc[100005];
int num1[27],num2[27],cnt1[27],cnt2[27];
int ans1=0,ans2=0,w1,w2;
void solve1()
{
int p=inf;
for(int i=0;b[i]!='\0';i++)
{
int m=b[i]-'a';
           cnt1[m]++;
           p=min(p,num1[m]/cnt1[m]);
}
        ans1+=p;
        w1=p;
for(int i=0;b[i]!='\0';i++)
{
int m=b[i]-'a';
           num1[m]-=p;
}

        memset(cnt1,0,sizeof(cnt1));
        p=inf;
for(int i=0;c[i]!='\0';i++)
{
int m=c[i]-'a';
           cnt1[m]++;
           p=min(p,num1[m]/cnt1[m]);
}
        ans1+=p;
for(int i=0;c[i]!='\0';i++)
{
int m=c[i]-'a';
           num1[m]-=p;
}
}

void solve2()
{
int p=inf;
for(int i=0;c[i]!='\0';i++)
{
int m=c[i]-'a';
           cnt2[m]++;
           p=min(p,num2[m]/cnt2[m]);
}
// printf("||p:%d\n",p);
        ans2+=p;
// printf("ans21:%d  1:%d\n",ans2,p);
        w2=p;
for(int i=0;c[i]!='\0';i++)
{
int m=c[i]-'a';
           num2[m]-=p;
}

        memset(cnt2,0,sizeof(cnt2));
        p=inf;
for(int i=0;b[i]!='\0';i++)
{
int m=b[i]-'a';
           cnt2[m]++;
           p=min(p,num2[m]/cnt2[m]);
}
// printf("2:%d\n",p);
        ans2+=p;
//printf("ans2:%d\n",ans2);
for(int i=0;b[i]!='\0';i++)
{
int m=b[i]-'a';
           num2[m]-=p;
}

}
int main()
{
while(~scanf("%s",a))
{
        scanf("%s",b);
        scanf("%s",c);
        memset(num1,0,sizeof(num1));
        memset(num2,0,sizeof(num2));
        memset(cnt1,0,sizeof(cnt1));
        memset(cnt2,0,sizeof(cnt2));
        ans1=ans2=0;

for(int i=0;a[i]!='\0';i++)
{
int k=a[i]-'a';
                num1[k]++;
                num2[k]++;
}

        solve1();
        solve2();

if(ans1>ans2)
{
int i;
for(i=1;i<=w1;i++)
                printf("%s",b);
for(;i<=ans1;i++)
                printf("%s",c);
for(int j=0;j<=25;j++)
for(int i=1;i<=num1[j];i++)
                 printf("%c",'a'+j);
            printf("\n");
}

else
{
int i;
for(i=1;i<=w2;i++)
                printf("%s",c);
for(;i<=ans2;i++)
                printf("%s",b);
for(int j=0;j<=25;j++)
for(int k=1;k<=num2[j];k++)
                 printf("%c",'a'+j);
            printf("\n");
//printf("||");
}
//cout<<w1<<" "<<ans1<<" "<<w2<<" "<<ans2<<endl;
}
return 0;
}