Minimum string representation

definition:

Denotes:
If a string for \ (S \) , and another string \ (S ^ \ prime \)
if there is a \ (I \) such \ (S ^ \ prime [i ... N] S ^ \ prime [1 ... i-1 ] \) and \ (S \) are equal, say \ (S ^ \ prime \) is \ (S \) a representation (also called \ (S ^ \ prime \) and \ (S \) cycle isomorphic).
\ (S \) is the smallest satisfies the above conditions is represented by the lexicographically smallest of \ (S ^ \ prime \)


Algorithm complexity

We take a look at the complexity of the violence:
\ (O (the n-^ 2) \)
at the beginning of the enumeration represented the smallest, to determine whether the cycle of violence isomorphic.
This approach is time consuming mainly on the comparison, if it is random data, perform well, but if this is:
\ [... aaaa aaa \]
every time the number of comparisons will reach \ (O (n) \) level the entire algorithm became \ (O (n ^ 2)
\) and the complexity of the algorithm we are going to be properly properly \ (O (n) \)


Rational solution

We consider two strings \ (A, B \) , they \ (S \) in the starting position are \ (I, J \) , and their front \ (K \) bits are equal.
If \ (A [i + k] > B [j + k] \) then for any string \ (T \) , which is located at the beginning \ (I \) and \ (i + k \) between, then it certainly will not be the optimal solution (think about why).
So we can directly \ (i \) Skip \ (i + k + 1 \) .
The complexity of the proof: no. . .


Template title

Luogu
Code:

/*--------------------------------
--Author: The Ace Bee-------------
--Blog: www.cnblogs.com/zsbzsb----
--This code is made by The Ace Bee
--------------------------------*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#include <string>
#define rg register
#define clr(x, y) memset(x, y, sizeof x)
using namespace std;
template < typename T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while (!isdigit(c)) f |= (c == '-'), c = getchar();
    while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
    s = f ? -s : s;
}

const int _ = 30010;

int n, L; char s[_], t[_];

inline void solve() {
    scanf("%s", s), L = strlen(s);
    int k = 0, i = 0, j = 1;
    while (k < L && i < L && j < L) {
        int tmp = s[(i + k) % L] - s[(j + k) % L];
        if (tmp == 0) ++k;
        else {
            if (tmp < 0) j += k + 1;
            if (tmp > 0) i += k + 1;
            if (i == j) ++i; k = 0;
        }
    }
    printf("%d\n", min(i, j) + 1);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
#endif
    read(n);
    for (rg int i = 1; i <= n; ++i) solve();
    return 0;
}

Guess you like

Origin www.cnblogs.com/zsbzsb/p/11627122.html