Naming Company CodeForces
阿新 • • 發佈:2019-01-04
有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; }