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; }