HDU 2609 How many(最小表示法)

Problem Description

Give you n ( n < 10000) necklaces ,the length of necklace will not large than 100,tell meHow 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

4011011001001001141010010110000001

Sample Output

12

对于一类前后成环可以循环的的题目,,判断同构的时候就要用到了最小

表示法:所谓最小表示法就是将一个字符串看成首尾相连然后就是表示

成字典序最小来判断是否同构.回到本题:用set存一下字符串即可。。

#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<string>#include<iostream>#include<queue>#include<cmath>#include<map>#include<stack>#include<set>using namespace std;#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define CLEAR( a , x ) memset ( a , x , sizeof a )typedef long long LL;typedef pair<int,int>pil;const int INF = 0x3f3f3f3f;const int maxn=1e4+100;char str[110];set<string>s;int n;int GetMin(char s[]){int len=strlen(str);int i=0,j=1,k;while(i<len&&j<len){for(k=0;k<len;k++)if(str[(i+k)%len]!=str[(j+k)%len])break;if(str[(i+k)%len]>str[(j+k)%len])i+=k+1;else j+=k+1;if(i==j) j++;}return min(i,j);}int main(){char temp[110];while(~scanf("%d",&n)){s.clear();REP(i,n){scanf("%s",str);int cnt=0;int pos=GetMin(str);int len=strlen(str);for(int j=pos;j<len;j++)temp[cnt++]=str[j];for(int j=0;j<pos;j++)temp[cnt++]=str[j];temp[cnt]='\0';s.insert(temp);}printf("%d\n",s.size());}return 0;}

走马观花之外,这才是深入体验,探索自我的最佳时间,

HDU 2609 How many(最小表示法)

相关文章:

你感兴趣的文章:

标签云: