手链样式--蓝桥杯

 

小明有3颗红珊瑚,4颗白珊瑚,5颗黄玛瑙。
他想用它们串成一圈作为手链,送给女朋友。
现在小明想知道:如果考虑手链可以随意转动或翻转,一共可以有多少不同的组合样式呢?
 
分析:这个题首先一定要理解题意,转动和翻转是个什么意思,转动就是我们所得到的的排列是个环,即起点不固定,具体点说即使1234和2341是一种方式(3421也一样)。翻转就是,这个排列是个立体的,可以上下左右翻转, 具体点说即

  1             1

 

 

2   3  和  3   2 是一样的(左右翻转),弄清了题意,就能事半功倍。
   4            4
方法一:利用数学的排列组合进行求解,首先我们科普一个小的知识,见图:

 

 

意思很明白了,这个题,我们就是先C(12,3)选出红珊瑚的位置,在 C(9,5)选出黄马瑙的位置,这就是总的情况了,由于是环排列,我们将结果除以12,得到不考虑翻转的情况,然后再考虑翻转的时候要考虑到对称的情形,这种翻转是没有影响的,
对称即   

 

 

               A
         A         A
         B         B
         B         B
         C         C
         C         C
              C
这种类型,这种情形的一共有C(5,2)*C(3,2) = 30种(只看一侧的),那么结果即:(2310-30)/2+30 = 1170;(立体排列除以2)

 

 

 

方法二:暴力枚举,我们直接把每一次得到的串先复制拼接一下(模拟旋转)成环,再翻转一下,如果两次得到的串在已得的串里面没有就加入,直接看代码吧,挺清楚的,鉴于c++里面有直接全排列去重的方法,那么我借鉴了,Java没有啊,直接写很麻烦。。。。
 
#include <iostream>  
#include <algorithm>  
#include <string>  
#include <vector>  
using namespace std;  
  
vector<string> v;     //存储已经找出的情况  
  
int sum = 0;  
  
int main(){  
    string str = "aaabbbbccccc";  
    do{  
        vector<string>::iterator it;  
        for(it=v.begin(); it != v.end(); it++){  
            if((*it).find(str, 0) != string::npos){  //如果在已得的里面能找到,就判断下一个
                break;  
            }  
        }  
        if( it != v.end() ) continue;  
        string str2 = str + str;  
        v.push_back(str2);  
        reverse(str2.begin(), str2.end());     //需要algorithm头文件  
        v.push_back(str2);  
        sum ++;  
    }while(next_permutation(str.begin(), str.end()));  
    cout << sum ;  
}  

 

 

 

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值