题意:给n个长度100以内的字符串,如果两个字符串循环移位可以得到相等的结果,那么就认为这两个字符串相等。求这n个字符串一共包含多少个不同的字符串。
思路:显然每个串循环移位得到的最小值是一定的,可以先用最小表示法处理出每个字符串的最小值,排个序,然后只需比较相邻的两个串是否相同就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
const int maxn = 1005;
typedef long long ll;
char s[201];
struct node{
char s[101];
bool operator < (const node &b) const{
return strcmp(s, b.s) < 0;
}
}str[10001];
int MINR(char s[], int l){
for(int i=0; i<l; ++i){
s[l + i] = s[i];
}
s[2 * l] = 0;
int i = 0, j = 1;
while(i < l && j < l){
int k = 0;
while(s[i + k] == s[j + k] && k < l){
++k;
}
if(k == l) break;
if(s[i + k] > s[j + k]) i = max(i + k + 1, j + 1);
else j = max(j + k + 1, i + 1);
}
return i < j ? i : j;
}
int main(){
int n, len;
while(~scanf("%d", &n)){
for(int i=0; i<n; ++i){
scanf("%s", s);
len = strlen(s);
int pos = MINR(s, len);
for(int j=0; j<len; ++j){
str[i].s[j] = s[j + pos];
}
str[i].s[len] = 0;
}
sort(str, str + n);
int ans = 1;
for(int i=1; i<n; ++i){
if(strcmp(str[i].s, str[i - 1].s) != 0){
++ans;
}
}
printf("%d\n", ans);
}
return 0;
}