4 0110 1100 1001 0011 4 1010 0101 1000 0001
1 2
题意:输入n串二进制的字符串,将其看成项链,问有多少种项链,第一次WA了发现并不是直接map就可以做的,还要将字符串先转换成一种统一的,比如abcde(为了方便表示就用字母了)与cdeab是一样的,相当于把这串字符串头尾连起来,从不同的视角看过去就显示不一样了,那重点就是把这些不同角度的项链统一成一个角度的。按照最小字典序进行统一。最小表示法的模版是网上找的,但是这个模版只能返回一个开始位置整数,拿来修改了一下就可以了。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<queue> #include<set> #include<map> #include<sstream> #include<algorithm> #include<cmath> #include<cstdlib> using namespace std; string zxc(string s,const int &l) { int i = 0, j = 1, k = 0, t; while(i < l && j < l && k < l) { t = s[(i + k) >= l ? i + k - l : i + k] - s[(j + k) >= l ? j + k - l : j + k]; if(!t) k++; else { if(t > 0) i = i + k + 1; else j = j + k + 1; if(i == j) ++ j; k = 0; } } int q=min(i,j);//这里本要返回q(最小表示的起始位置),这里先利用一下 s+=s;//首先要把字符串自增一下 s=s.substr(q,l);//(起始位置,原来长度) return s;//返回最小表示的字符串 } int main (void) { string s; int t,n; while (cin>>n) { map<string,int>list;//无脑map开始了...... for (int i=0; i<n; i++) { cin>>s; list[zxc(s,s.size())]=0; } cout<<list.size()<<endl; } return 0; }