第六届蓝桥杯省赛C++A组 手链样式(全排列+字符串判断(STL处理))

题目描述
小明有3颗红珊瑚,4颗白珊瑚,5颗黄玛瑙。
他想用它们串成一圈作为手链,送给女朋友。
现在小明想知道:如果考虑手链可以随意转动或翻转,一共有多少不同的组合样式?

输出
请你输出该整数。不要输出任何多余的内容或说明性的文字。

首先一定要理解题意
转动和翻转是个什么意思,转动就是我们所得到的的排列是个环,即起点不固定,具体点说即使1234和2341是一种方式(3421也一样)。翻转就是,这个排列是个立体的,可以上下左右翻转

在这里插入图片描述
如何判断是否串是已经出现过的情况比较难想,下面提供一种思路
判断转动情况是否存在,可把字符串复制一份,查看其子串里是否含有某种字符串
如abcabc变为abcabcabcabc存起来
当要判断cabcab是否存在时,只需判断cabcab是否是abcabcabcabc的子串。
翻转用reverse函数翻转,再查看是否存在
注意翻转和转动可能同时存在,所以要把翻转传也要复制一份存起来。
注意翻转字符串一定不能直接翻转当前的串,因为当前传要完成全排列来模拟所有的情况,一旦翻转了串会认为已经变化了。所以翻转要翻转与其值相同的另外的串。
判断当前字符串是否已经存在使用的是vector,在每次插入新字符串之前要查重判断。判断函数 if(v[i].find(s) != string::npos)
string::npos如果作为一个返回值(return value)表示没有找到匹配项。
详细用法见string::npos的一些说明
代码如下

#include <iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<math.h>
#include<cmath>
#include<string>
using namespace std;
int main()
{
	string s = "aaabbbbccccc";//模拟345三种宝石串
	vector<string>v;
	int ans = 0;
	int quitflag;
	do
	{
		quitflag = 1;
		for(int i=0;i<v.size();i++)
		{
			if(v[i].find(s) != string::npos) //没到最后就找到了,说明有重复
			{
				quitflag = 0;
				break;
			}
		}
		if(quitflag == 0) continue;//如果找到重复的就跳过本次循环
		string s2 = s+s;
		v.push_back(s2);//两串相加用来判断转动
		reverse(s2.begin(),s2.end());//翻转
		v.push_back(s2);//翻转用来判断串翻转后相等的情况
		ans++;
	}while(next_permutation(s.begin(),s.end()));//全排列找出所有串的组合情况
	cout<<ans;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值