POJ 1509 Glass Beads【字符串最小表示法】

题目链接:

http://poj.org/problem?id=1509

题意:

求循环字符串的最小表示。

分析:

浅析“最小表示法”思想在字符串循环同构问题中的应用
判断两字符串是否是循环同构的过程就是在求字符串的最小表示,即如果两个字符串是循环同构的,那么当前两指针i=M(s1)j=M(s2) 的时候,一定可以得到u[ii+s11] = w[jj+s21]
所以我们把给定序列看成两个循环同构的字符串,然后求一下最小表示就好了。

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define pr(x) cout << #x << ": " << x << "  "
#define pl(x) cout << #x << ": " << x << endl;
const int maxn = 20000 + 5;
int n;
char a[maxn];
int solve()
{
    int i = 0, j = 1, k;
    while(i < n && j < n)
    {
        for(k = 0; k < n; k++){
            if(a[(i + k) % n] != a[(j + k) % n]){
                break;
            }
        }
        if(k == n) break;
        if(a[(i + k) % n] > a[(j + k) % n])  i = i + k + 1;
        else j = j + k + 1;
        if(i == j) j = i + 1;
    }
    return i < j ? i : j;
}
int main()
{
    int t;scanf("%d", &t);
    while(t--){
        scanf("%s", a);
        n = strlen(a);
        printf("%d
", solve() + 1);
    }
    return 0;
}

最小表示法思想:

当某两个对象有多种表达形式,且需要判断它们在某种变化规则下是否能够达到一个相同的形式时,可以将它们都按一定规则变化成其所有表达形式中的最小者,然后只需要比较两个“最小者”是否相等即可。

原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758636.html