How many
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2184 Accepted Submission(s): 904
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
用最小表示法返回字符串能旋转的最小的字典序。set记录一下数一数就好了。最大表示法和最小表示法基本上一样,就是判断的语句换了一下。
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <set> using namespace std; const int maxn = 1e4 + 10; char s[maxn][110]; int len; set<string> st; int GetMin(int id) { int i = 0, j = 1, k = 0; while(i < len && j < len && k < len) { int t = s[id][(i + k) % len] - s[id][(j + k) % len]; if(!t) k++; else { if(t < 0) j = j + k + 1; else i = i + k + 1; if(i == j) j++; k = 0; } } return min(i, j); } /*int getMax() { int i = 0, j = 1, k = 0; while(i < len && j < len && k < len) { int t = s[(i + k) % len] - s[(j + k) % len]; if(!t) k++; else { if(t > 0) j = j + k + 1; else i = i + k + 1; if(i == j) j++; k = 0; } } return min(i, j); }*/ int main() { int n; while(~scanf("%d", &n)) { st.clear(); for(int i = 1; i <= n; i++) { scanf("%s", s[i]); } for(int i = 1; i <= n; i++) { string tmp; len = strlen(s[i]); int Min = GetMin(i); for(int j = 0; j < len; j++) { tmp += s[i][(Min + j) % len]; } //if(!st[tmp]) st.insert(tmp); } cout << st.size() << endl; } }
时间: 2024-10-10 07:43:39