最小表示法+Trie。首先用最小表示法把所有的串都表示成字典序最小的串,然后把所有的串都放Trie中判断不同串的个数就可以了。
#include<algorithm> #include<iostream> #include<cstring> #include<fstream> #include<sstream> #include<cstdlib> #include<vector> #include<string> #include<cstdio> #include<bitset> #include<queue> #include<stack> #include<cmath> #include<map> #include<set> #define FF(i, a, b) for(int i=a; i<b; i++) #define FD(i, a, b) for(int i=a; i>=b; i--) #define REP(i, n) for(int i=0; i<n; i++) #define CLR(a, b) memset(a, b, sizeof(a)) #define debug puts("**debug**") #define LL long long #define PB push_back #define MP make_pair using namespace std; const int N = 1001000; int chd[N][2], tot; bool val[N]; int Trie(char *s) { int q = 0; for(; *s; s ++) { int p = *s - '0'; if(!chd[q][p]) { CLR(chd[tot], 0); chd[q][p] = tot ++; } q = chd[q][p]; } if(val[q]) return 0; val[q] = true; return 1; } int Minpri(char *s) { int i = 0, j = 1, k = 0, t, len; len = strlen(s); while (i < len && j < len && k < len) { t = s[(i+k)%len] - s[(j+k)%len]; if (t == 0) k ++; else { if (t > 0) i += k + 1; else j += k + 1; if (i == j) j ++; k = 0; } } return min(i,j); } char c[110], cp[110]; int main() { int n, len, ans; while(scanf("%d", &n) != EOF) { ans = 0;tot = 1; CLR(val, false);CLR(chd[0], 0); for(int i = 0; i < n; i ++) { scanf("%s", c); int t = Minpri(c); len = strlen(c); for(int j = 0; j < len; j ++) { cp[j] = c[(j + t) % len]; } cp[len] = '\0'; ans += Trie(cp); } printf("%d\n", ans); } }