题意:给你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;
}