hdu 2609 How many(最小表示法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2609

题意:给你n个字符串每个字符串可以左右移动但还是同一串比如 0110 可以表示为 0110 -> 1100 -> 1001 -> 0011->0110

这些都属于同一个字符串,最后问这n个字符串里一共有多少不同的字符串

 

可以将这些字符串都以其最小表示方法存下来复杂度为O(n)然后在sort一遍找一下有几个不同的就行了。

 

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int M = 1e4 + 10;
char sl[1000];
struct TnT {
    char sm[1000];
}T[M];
int Minnum(char s[] , int l){
    int i = 0 , j = 1 , k = 0 , t;
    while(i < l && j < l && k < l){
        t = s[(i + k) >= l ? i + k - l : i + k] - s[(j + k) >= l ? j + k - l : j + k];
        if(!t) k++;
        else {
            if(t > 0) i = i + k + 1;
            else j = j + k + 1;
            if(i == j) j++;
            k = 0;
        }
    }
    return i;
}
bool cmp(TnT a , TnT b) {
    return strcmp(a.sm , b.sm) <= 0;
}
int main() {
    int n;
    while(scanf("%d" , &n) != -1) {
        for(int i = 0 ; i < n ; i++) {
            scanf("%s" , sl);
            int len = strlen(sl);
            int pos = Minnum(sl , len);
            int num = 0;
            for(int j = pos ; j < len ; j++) {
                T[i].sm[num++] = sl[j];
            }
            for(int j = 0 ; j < pos ; j++) {
                T[i].sm[num++] = sl[j];
            }
            T[i].sm[num] = '\0';
        }
        sort(T , T + n , cmp);
        int ans = 1;
        for(int i = 1 ; i < n ; i++) {
            if(strcmp(T[i].sm , T[i - 1].sm) != 0) {
                ans++;
            }
        }
        printf("%d\n" , ans);
    }
    return 0;
}
posted @ 2017-04-16 20:16  Gealo  阅读(269)  评论(0编辑  收藏  举报