How many(HDU-2609)

题面

Give you n ( n < 10000) necklaces ,the length of necklace will not large than 100,tell me How many kinds of necklaces total have.(if two necklaces can equal by rotating ,we say the two necklaces are some). For example 0110 express a necklace, you can rotate it. 0110 -> 1100 -> 1001 -> 0011-> 0110.

输入

The input contains multiple test cases. Each test case include: first one integers n. (2<=n<=10000) Next n lines follow. Each line has a equal length character string. (string only include ‘0’,‘1’).

输出

For each test case output a integer , how many different necklaces.

样例输入

 14
 20110
 31100
 41001
 50011
 64
 71010
 80101
 91000
100001

样例输出

11
22

提示

思路

先用最小表示法,求出最小字典序,然后map去重。

代码

 1string s;
 2
 3int getmin(int n)
 4{
 5    int i=0, j=1, k=0;
 6    while(i<n && j<n && k<n)
 7    {
 8        if(s[(i+k)%n] == s[(j+k)%n]){
 9            k++;
10        }else{
11            if(s[(i+k)%n] > s[(j+k)%n])
12                i+=k+1;
13            else
14                j+=k+1;
15            k = 0;
16            if(i == j) i++;
17        }
18    }
19    return min(i, j);
20}
21
22int main()
23{
24    int n;
25    while(~scanf("%d", &n))
26    {
27        map<string, int> mp;
28        int ans = 0;
29        for(int i=0; i<n; i++)
30        {
31            cin >> s;
32            string ss = "";
33            int st = getmin(s.length());
34            for(int i=st; i<s.length(); i++) ss += s[i];
35            for(int i=0; i<st; i++) ss += s[i];
36            if(mp[ss] == 0){
37                mp[ss] = 1;
38                ans++;
39            }
40        }
41        printf("%d\n", ans);
42    }
43    return 0;
44}