题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2609
题目大意:
题目大意有n个有01组成的字符串,每个字符串都代表一个项链,
那么该字符串就是一个环状的结构,求可以经过循环旋转,例如0110 -> 1100 -> 1001 -> 0011->0110,最后不同的串有多少个。
解题思路:求出各个字符串的最小表示,加进set去重就好了。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
const int N=1e6+; int len;
char p[N]; //求最大/最小表示
int min_max_express(int flag){
int i=,j=,k=;
while(i<len&&j<len&&k<len){
int t=p[(i+k)%len]-p[(j+k)%len];
if(t==) k++;
else{
if(flag){
if(t<) j+=k+;
else i+=k+;
}
else{
if(t>) j+=k+;
else i+=k+;
}
if(i==j) j++;
k=;
}
}
return min(i,j);
} int main(){
int n;
while(~scanf("%d",&n)){
set<string>st;
for(int i=;i<n;i++){
scanf("%s",p);
len=strlen(p);
char tmp[];
int cnt=,min_idx;
min_idx=min_max_express();
for(int j=;j<len;j++){
int idx=(min_idx+j)%len;
tmp[cnt++]=p[idx];
}
tmp[cnt]='\0';
st.insert(tmp);
}
printf("%d\n",st.size());
}
return ;
}