Codeforces 1316B String Modification

题目链接

给定一个串,问以长度k反转串,求字典序最小的k值

假定有一个串(s_{1}s_{2}..s_{n}), 长度k反转一次, 有(s_{k}s_{k-1}..s_{1}s_{k+1}s_{k+2}..s_{n}), 以此类推,第二次, (s_{k}s_{k+1}s_{1}..s_{k-1}s_{k+2}..s_{n}), 分析不难找到规律,每一次长度为k, 则(s_k-s_n)不变,变成前缀, (s_1-s_{k-1})接在其后,而接在其后的这一串是正序还是逆序跟(k)(n)有关,若奇偶性相同,则需要逆序,否则正序

#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
typedef long long LL;
typedef pair<int,int> pii;



void run_case() {
    int n; string str;
    cin >> n >> str;
    int ansk = 1;
    string anss = str;
    for(int i = 2; i <= n; ++i) {
        string pre = str.substr(0, i-1);
        string suff = str.substr(i-1, n);
        if(i % 2 == n % 2) reverse(pre.begin(), pre.end());
        string now = suff + pre;
        if(now < anss) {
            anss = now;
            ansk = i;
        } 
    }
    cout << anss << "
" << ansk << "
";
}

int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    cout.flags(ios::fixed);cout.precision(2);
    int t; cin >> t;
    while(t--)
    run_case();
    cout.flush();
    return 0;
}
原文地址:https://www.cnblogs.com/GRedComeT/p/12444310.html