蓝桥杯 手链翻转

版权声明:转载请注明出处https://blog.csdn.net/hhmy77 https://blog.csdn.net/hhmy77/article/details/88694473

一道填空题,不考虑时间复杂度。
我一开始想的是可以每找到一个原生字符串(即可以生成所有其它字符串的字典序最小字符串),然后循环生成每个它的子字符串一起存到vector中,每次碰到新的查找即可。但是我没想到怎么找到这个所谓的原生字符串,想过压缩字符串来存储,但是还是没有实现。
上网搜了一下题解 发现每找到一个新的字符串,把它扩大两倍,它的所有子串都能在这个两倍的字符串中找到。
比如

abc 
cab
bca
把上述串首尾相连 abcabbca 然后压缩相同字符就变成了
abcabc

而且一个串能循环生成的串数量是该串的长度
还有需要注意的是一个串和一个串的翻转并不相同,所以我们还要存储翻转后的串
上述那个扩大两倍我确实没想到,确实能验证这样做是正确的,但是这样做的依据是什么的?

#include<bits/stdc++.h>
using namespace std;
//a 3 b 4 c 5
//全选然后问有多少组合 可以转动(循环) 翻转 即aaabbbbccccc=caaabbbcccc 
//由一个初始的序列 生成所有的序列 
//因为可以转动手链 可以把字符串乘2可以在这个大字符串中就可以查找到所有的生成情况! 一般来说可以生成的情况是串的两倍 
//需要注意的是 手链和反转后的手链并不相同,
//如 a3b4c5 翻转后 c5b4a3 两个是不同的 
int ans=0; 
int main()
{
	vector<string>vts;
	int ans=0;
	string str="aaabbbbccccc";
	do
	{
		bool ok=true;
		for(int i=0;i<vts.size();i++)
		{
			if(vts[i].find(str)!=string::npos)
			{
				ok=false;
				break;
			}
		}
		if(ok)
		{
			string tmp=str;
			vts.push_back(tmp+tmp);
				reverse(tmp.begin(),tmp.end());
			vts.push_back(tmp+tmp);
			ans++;
		}
	}while(next_permutation(str.begin(),str.end()));
	cout<<ans;
}

猜你喜欢

转载自blog.csdn.net/hhmy77/article/details/88694473