Naming Company CodeForces - 794C (贪心+博弈)
有2个人分别叫A和B,A有s串,B有t串,然后构造出一个新串,A希望新串字典序尽可能小,B希望新串字典序尽可能大,然后是A先放字符进新串(即A先手),这样轮流放直到新串长度为len,这里以len为偶为例子,那就从s串和t串里分别取前len/2小,和前len/2大作为新串的字符,然后接下来就是如何安排字符位置的问题了(即贪心策略),以下文字都是视s串元素只有前len/2小,t串元素只有前len/2大而言,因为A希望字典序最小,1.所以当s的最小的元素值小于t串里最大的元素时,直接放新串的最前面。2.当s的最小的元素值大于等于t串里的最大元素时,这时候显然还把s的最小的元素直接放新串的最前面这样这样对A来说肯定不是字典序最小的,换个角度想想,当s的最小的元素值大于等于t串里的最大元素时,s里的最大元素显然是s串和t串里可选字符里最大的那个了,所以A为了字典序最小就要把最大的放新串后面,占住后面的位子,因为如果不这样做的话,即s里的最大元素占了其他位置的话,显然最后得到的新串对A来说不是字典序最小的。对B的操作也是一样的。
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
char s[maxn],t[maxn],ans[maxn];
bool cmp(const char&a,const char&b)
{
return a>b;
}
int main()
{
int len,slo,sup,tlow,tup,anslow,ansup;
cin>>s+1>>t+1;
len=strlen(s+1);
sort(s+1,s+len+1);
sort(t+1,t+len+1,cmp);
if(!(len%2))//偶数
{
int flag=1;
slo=1,sup=len/2;
tlow=1,tup=len/2;
anslow=1,ansup=len;
while(anslow<=ansup)
{
if(flag==1)//放s串里的字符
{
if(tlow<=tup&&s[slo]>=t[tlow])//等于一定要加
{
ans[ansup--]=s[sup--];
}
else
{
ans[anslow++]=s[slo++];
}
}
else
{
if(slo<=sup&&t[tlow]<=s[slo])
{
ans[ansup--]=t[tup--];
}
else
{
ans[anslow++]=t[tlow++];
}
}
flag=-flag;
}
}
else//长度为奇数
{
int flag=1;
slo=1,sup=len/2+1;
tlow=1,tup=len/2;
anslow=1,ansup=len;
while(anslow<=ansup)
{
if(flag==1)
{
if(tlow<=tup&&s[slo]>=t[tlow])
{
ans[ansup--]=s[sup--];
}
else
ans[anslow++]=s[slo++];
}
else
if(slo<=sup&&t[tlow]<=s[slo])
{
ans[ansup--]=t[tup--];
}
else
ans[anslow++]=t[tlow++];
flag=-flag;
}
}
for(int i=1;i<=len;i++)
cout<<ans[i];
cout<<endl;
return 0;
}