How many
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3553 Accepted Submission(s): 1592
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
串的最小表示
设S=bcad,且S’是S的循环同构的串。S’可以是bcad或者cadb,adbc,dbca。而且最小表示的S’是adbc。
对于字符串循环同构的最小表示法,其问题实质是求S串的一个位置,从这个位置开始循环输出S,得到的S’字典序最小。
思路:找出每个字符串的最下表示加入set容器(可以去掉重复的),最后输出set容器中元素的个数。
//串的最小表示,并保存在set中 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<set> #include<algorithm> using namespace std; const int N=205; int n,len; set<string>v; char s[N],t[N]; int min_Represstation(char *s) { int i=0,j=1,k=0; while(i<len&&j<len&&k<len){ int tmp=s[(i+k)%len]-s[(j+k)%len]; if(tmp==0) k++; else{ if(tmp>0) i+=k+1; else j+=k+1; if(i==j) j++; k=0; } } return min(i,j); } void getMin(char *str){ str[len/2]='\0'; v.insert(str); } int main() { while(~scanf("%d",&n)) { v.clear(); for(int i=0;i<n;i++) { scanf("%s",t); strcpy(s,t); strcat(s,t); len=strlen(s); int k=min_Represstation(s); getMin(s+k); } printf("%d\n",v.size()); } return 0; }
C++的string保存每个字符串的最小表示+排序
#include<stdio.h> #include<iostream> #include<string> #include<algorithm> using namespace std; string s[11000]; string minmize(string ss) { int t,len; string mstr,a; len=ss.length(),t=len; mstr=ss; while(t--) { a=ss[0]; ss=ss.substr(1);//取子字符串函数,从字符串的第二个字符开始到结束 ss+=a; if(mstr>ss) mstr=ss; } return mstr; } int main() { ios::sync_with_stdio(false);//加快cin,cout的速度 cin.tie(0); int n; string si; while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++) { cin>>si; s[i]=minmize(si); } sort(s,s+n); int cnt=1; for(int i=0;i<n-1;i++) if(s[i]!=s[i+1]) cnt++; cout<<cnt<<endl; } }