2019牛客暑期多校训练营(第七场)- String

乱搞

先把每段按1结尾分开,然后暴力合并,合并的条件是每段字符串的字典序都不下降,这样可以保证是最小表示。

因为如果后面有一段字典序比前面合并的任意一段字典序小,那它放到这段合并的字符串最前面显然可以更小,因此不符合最小表示,这段不需要合并。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define full(a, b) memset(a, b, sizeof a)
#define __fastIn ios::sync_with_stdio(false), cin.tie(0)
#define range(x) (x).begin(), (x).end()
#define pb push_back
using namespace std;
typedef long long LL;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
    int ret = 0, w = 0; char ch = 0;
    while(!isdigit(ch)){
        w |= ch == '-', ch = getchar();
    }
    while(isdigit(ch)){
        ret = (ret << 3) + (ret << 1) + (ch ^ 48);
        ch = getchar();
    }
    return w ? -ret : ret;
}
template <typename A>
inline A lcm(A a, A b){ return a / __gcd(a, b) * b; }
template <typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
    A ans = 1;
    for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
    return ans;
}
string s;
int _;
int main(){

    __fastIn;
    for(cin >> _; _; _ --){
        cin >> s;
        vector<string> v, ans;
        string t = "";
        t.pb(s.front());
        for(int i = 1; i < s.size(); i ++){
            if((s[i] == '0' && s[i - 1] == '1')){
                v.pb(t), t.clear();
            }
            t.pb(s[i]);
        }
        if(!t.empty()) v.pb(t);
        bool ok = false;
        while(!ok){
            bool y = false;
            for(int i = 0; i < v.size(); i ++){
                string str = v[i];
                int j = i + 1;
                while(j < v.size() && v[j - 1] <= v[j]) str += v[j], j ++, y = true;
                ans.pb(str), i = j - 1;
            }
            if(!y) ok = true;
            v = ans, ans.clear();
        }
        for(int i = 0; i < v.size(); i ++){
            cout << v[i];
            if(i != v.size() - 1) cout << " ";
        }
        cout << endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/onionQAQ/p/11324030.html