String 2019牛客暑期多校训练营(第七场)(最小表示法)

这篇博客探讨了如何判断一个01字符串是否完美,即具有最小字典序的循环旋转。通过给出的示例和解题思路,介绍了利用最小表示法检查字符串并将其拆分为最少且完美的部分,涉及递归操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:https://ac.nowcoder.com/acm/contest/887/A
来源:牛客网
 

题目描述

A string is perfect if it has the smallest lexicographical ordering among its cyclic rotations.
For example: "0101" is perfect as it is the smallest string among ("0101", "1010", "0101", "1010").

Given a 01 string, you need to split it into the least parts and all parts are perfect.

输入描述:

The first line of the input gives the number of test cases, T (T≤300)T\ (T \leq 300)T (T≤300).  test cases follow.

For each test case, the only line contains one non-empty 01 string. The length of string is not exceed 200.

输出描述:

For each test case, output one string separated by a space.

示例1

输入

复制

4
0
0001
0010
111011110

输出

复制

0
0001
001 0
111 01111 0

解题思路:对于每个字符串用最小表示法去判断是不是字典序最小的,如果不是从后开始删减字符,把每个删减的字符也组成新的字符串,当然,相对位置不变。对每个新的字符串做如上操作。其实就是一个递归操作。

/*
@Author: Top_Spirit
@Language: C++
*/
#include <bits/stdc++.h>
using namespace std ;

int n ;
string s ;
vector < string > ans ;

int Mins(string s ){
    int len = s.size() ;
    int i = 0, j = 1, k = 0 ;
    while (i < len && j < len && k < len){
        int t = s[(i + k) % len] - s[(j + k) % len] ;
        if (!t) k++ ;
        else {
            if (t > 0) i += k + 1 ;
            else if (t < 0) j += k + 1 ;
            if (i == j) j = i + 1 ;
            k = 0 ;
        }
    }
    return min(i , j) ;
}

bool check(string s){
    string str = s ;
    s += str ;
    if (Mins(s) == 0) return true ;
    return false ;
}

void solve (string s ){
    int len = s.size() ;
    string str = "" ;
    for (int i = len - 1 ;i >= 0; i--){
        if (check(s)){
            ans.push_back(s) ;
            reverse(str.begin(), str.end()) ;
            solve(str) ;
            return ;
        }
        else {
            str += s[i] ;
            s.pop_back() ;
        }
    }
}

int main (){
    int T ;
    cin >> T ;
    while (T--){
        cin >> s ;
        ans.clear() ;
        solve(s) ;
        for (int i = 0; i < ans.size(); i++){
            if (i == 0) cout << ans[i] ;
            else cout << " " << ans[i] ;
        }
        cout << endl ;
    }
    return 0 ;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值