HDU 2609 -- 最小表示法

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2609
题目大意:给你一些串,问有多少个串是循环同构之后仍不同的
思路:典型的最小表示法题,对每一个串求一个最小循环表示,然后用set去重就好了
AC代码:

#include<bits/stdc++.h>
using namespace std;

char str[105], str2[205];
set<string> pp;

int minr(char s[], int l)
{
    int i = 0, j = 1, k = 0;
    while(i < l && j < l && k < l){
        if(s[i+k] == s[j+k])    k++;
        else{
            if(s[i+k] < s[j+k]) j += k+1;
            else    i += k+1;
            k = 0;
            if(i == j)  j++;
        }
    }
    return min(i, j);
}
int main()
{
    int T;
    while(~scanf("%d", &T)){
        pp.clear();
        while(T--){
            cin >> str;
            int len = strlen(str);
            for(int i = 0; i < len; i++){
                str2[i] = str[i];
            }
            for(int i = 0; i < len; i++){
                str2[i+len] = str[i];
            }
            int t = minr(str2, len);
            str2[t+len] = '\0';
            pp.insert(str2+t);
        }
        cout << pp.size() << '\n';
    }
    return 0;
}

附上最小表示法的模板:

int minr(char s[], int l)   //返回最小循环表示开始的位置
{
    int i = 0, j = 1, k = 0;
    while(i < l && j < l && k < l){
        if(s[i+k] == s[j+k])    k++;
        else{
            if(s[i+k] < s[j+k]) j += k+1;
            else    i += k+1;
            k = 0;
            if(i == j)  j++;
        }
    }
    return min(i, j);
}
    int t = minr(str2, len);    //str2 = 2*str
    str2[t+len] = '\0';
    printf("%s", str2+t);   //最小循环表示

猜你喜欢

转载自blog.csdn.net/water_zero_saber/article/details/81191690
今日推荐