乱搞
先把每段按1结尾分开,然后暴力合并,合并的条件是每段字符串的字典序都不下降,这样可以保证是最小表示。
因为如果后面有一段字典序比前面合并的任意一段字典序小,那它放到这段合并的字符串最前面显然可以更小,因此不符合最小表示,这段不需要合并。
#include#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_backusing 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 inline A lcm(A a, A b){ return a / __gcd(a, b) * b; }template 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 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;}