#414 Div2 C

#414 Div2 C

题意

两个人每个人都有一串字母序列,他们要替换一个长度为 n 包含问号的新序列,他们每次可以使用自己序列中的字母代替新序列的问号(使用自己序列中的字母后那个字母就会消失),第一个人想要形成的序列字典序尽可能小,第二个人则希望尽可能大,两人操作不失误,第一个人先操作,问形成的新序列。

分析

首先排序,如果 n 为偶数,显然第一个人用到的字母是自己序列的前一半,而后一个人则是自己序列的后一半,一开始两人都尽可能的想要把字典序小的字母或字典序大的字母向前放,直到第一个人所操作到的字母字典序大于等于第二个人操作到的字母的字典序,那么第一个人一定想把大的放到后面,第二个人想把小的放到后面,按这样的规则倒序插入剩下的数字即可。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 3e5 + 10;
string s1, s2;
char ans[MAXN];
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> s1 >> s2;
    sort(s1.begin(), s1.end());
    sort(s2.begin(), s2.end());
    int L = s1.length();
    int mxl = (L + 1) / 2;
    int l = 0, r = L - 1, c = 0, cnt = 0;
    int ff = 0;
    while(s1[l] < s2[r]) {
        ans[c++] = s1[l++];
        cnt++;
        if(cnt == L) break;
        if(s2[r] <= s1[l]) {
            ff = 1;
            break;
        } else {
            ans[c++] = s2[r--];
            cnt++;
        }
        if(cnt == L) break;
    }
    int rr = mxl; // 第二个序列需要填入的序列段的最左端
    mxl--; // 第一个序列需要填入的序列段的最右端
    for(int i = L - 1; i >= 0; i--) {
        if(ans[i] == 0) {
            if(!ff) {
                ans[i] = s1[mxl--];
                cnt++;
                ff = 1;
            } else {
                ans[i] = s2[rr++];
                ff = 0;
                cnt++;
            }
        }
        if(cnt == L) break;
    }
    ans[L] = 0;
    cout << ans << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/ftae/p/6930765.html