hdu2609 How many【最小表示法】【Hash】

How many

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4210    Accepted Submission(s): 1936


Problem Description
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.
 

 

Input
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').
 

 

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

 

Sample Input
4 0110 1100 1001 0011 4 1010 0101 1000 0001
 

 

Sample Output
1 2
 

 

Author
yifenfei
 

 

Source
 

 

Recommend
yifenfei
 

题意:

给定n个01串,统计一共有多少种不同的。如果他们的循环同构是相同的那他们就是相同的。

思路:

刚开始很暴力的把每个串的所有循环同构串都丢进set里,直接MLE了。太暴力了。

应该要想到如果串相同的话,他们的最小表示法肯定是一样的。所以只需要存最小表示法就可以了。

然后也不需要统计,直接print set的大小就可以了。

每输入一个数,找到他的最小表示法。

然后对这个最小表示法进行hash,结果丢进set

处理完所有字符串,print set的大小。

 1 #include<iostream>
 2 #include<bits/stdc++.h>
 3 #include<cstdio>
 4 #include<cmath>
 5 //#include<cstdlib>
 6 #include<cstring>
 7 #include<algorithm>
 8 //#include<queue>
 9 #include<vector>
10 //#include<set>
11 //#include<climits>
12 //#include<map>
13 using namespace std;
14 typedef long long LL;
15 typedef unsigned long long ull;
16 #define N 100010
17 #define pi 3.1415926535
18 #define inf 0x3f3f3f3f
19 
20 const int maxn = 1e4 + 4;
21 int n;
22 char str[105 * 2];
23 ull h[105];
24 set<ull>types;
25 
26 int main()
27 {
28     while(scanf("%d", &n) != EOF){
29         types.clear();
30         for(int i = 0; i < n; i++){
31             scanf("%s", str + 1);
32             int len = strlen(str + 1);
33             for(int j = 1; j <= len; j++)str[len + j] = str[j];
34             int j = 1, k = 2, p;
35             while(j <= len && k <= len){
36                 for(p = 0; p < n && str[j + p] == str[k + p];p++);
37                 if(p == len)break;
38                 if(str[j + p] > str[k + p]){
39                     j = j + p + 1;
40                     if(j == k)j++;
41                 }
42                 else{
43                     k = k + p + 1;
44                     if(j == k)k++;
45                 }
46             }
47             int pos = min(j, k);
48 
49             for(j = 1; j <= len; j++){
50                 h[j] = h[j - 1] * 131 + str[j + pos - 1] - '0';
51             }
52             types.insert(h[len]);
53         }
54         printf("%d\n", types.size());
55     }
56     return 0;
57 }

 

posted @ 2018-11-20 16:16  wyboooo  阅读(231)  评论(0编辑  收藏  举报