2015年蓝桥杯初赛] 手链样式 知识点:全排列

119 阅读1分钟

题目描述
小明有3颗红珊瑚,4颗白珊瑚,5颗黄玛瑙。
他想用它们串成一圈作为手链,送给女朋友。
现在小明想知道:如果考虑手链可以随意转动或翻转,一共有多少不同的组合样式?
输出
请你输出该整数。不要输出任何多余的内容或说明性的文字。

解析

题目说了如果考虑手链可以随意转动或翻转,什么意思呢?

就是说我们手上戴的手链,如果转动手腕,手链就发生了旋转,但是手链还是那个手链,这就是在告诉我们要去重。

这里我们要用到一个公式: image.png

验证:

我们发现,我们旋转s的时候,不论怎么旋转,旋转出来的s'都是s+s的子串: image.png

因此我们可以拿翻转后的s去s+s里找,找到了就说明重了,我们就把这种情况排除掉。

code

#include<bits/stdc++.h>
using namespace std;
int ans;
vector<string>v1;
int main()
{
	string s="aaabbbbccccc";  //3颗红珊瑚,4颗白珊瑚,5颗黄玛瑙
   do
   {
    int i=0;
    
    for(;i<v1.size();i++)
	{
	  if(v1[i].find(s)!=string::npos)break;  //如果找到了子串就提前终止 
	}   	
	
	if(i!=v1.size())continue; //如果提前终止说明重了,就结束这个情况 

	
	
   	string s2=s+s;
   	v1.push_back(s2);
   	reverse(s2.begin(),s2.end());
    v1.push_back(s2);
    
    ans++;
   }while(next_permutation(s.begin(),s.end()));


cout<<ans<<endl;
	return 0;
 } 

image.png