1. 程式人生 > >hdu2609 最小表示法

hdu2609 最小表示法

expr diff opened res str substr multiple min spa

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.

InputThe 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‘).
OutputFor 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
題意:給一些長度相同的01數列,要求求出不相同的個數(經過循環相同的也算相同)
題解:最小表示法(為啥分類到kmp裏面?)直接水過了,還以為要kmp之類的呢
技術分享
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<iomanip>
#include
<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 using namespace std; const int N=1000000+5,maxn=1000000+5,inf=1e9+5; int Next[N],slen; string str; void getnext() { Next[0]=-1; int k=-1; for(int i=1;i<slen;i++) {
while(k>-1&&str[k+1]!=str[i])k=Next[k]; if(str[k+1]==str[i])k++; Next[i]=k; } } int getmin() { int i=0,j=1,k=0; while(i<slen&&j<slen&&k<slen){ int t=str[(i+k)%slen]-str[(j+k)%slen]; if(!t)k++; else { t>0 ? i=i+k+1 : j=j+k+1; if(i==j)j++; k=0; } } return min(i,j); } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; while(cin>>n){ vector<string>v; for(int i=0;i<n;i++) { cin>>str; slen=str.size(); str=str.substr(getmin(),slen)+str.substr(0,getmin()); bool flag=1; for(int j=0;j<v.size();j++) if(v[j]==str) { flag=0; break; } if(flag)v.push_back(str); } cout<<v.size()<<endl; } return 0; }
View Code

hdu2609 最小表示法