hdu 2609 How many

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;
	}
 } 

猜你喜欢

转载自blog.csdn.net/qq_36914923/article/details/80185854