• 衔尾蛇【可重集合+圆圈排列】


    题意

    链接:https://ac.nowcoder.com/acm/contest/9854/D

    光、对立和小红三个人在玩捉蛇游戏。已知蛇有三种:红蛇、蓝蛇和绿蛇。蛇可以咬住自己的尾巴,形成衔尾蛇。每条蛇可以咬住自己的尾巴,也可以咬住别的蛇的尾巴。一共有 (a) 条红蛇,(b) 条蓝蛇,(c) 条绿蛇。她们想知道一共可以形成多少种不同的衔尾蛇的环?

    注:蛇可以不用全部用完。

    (1≤a+b+c≤12)

    分析

    数据范围很小,明显可以直接枚举每种颜色的蛇的数量,将每种情况累加起来。计算的时候按可重集合和圆圈排列直接用公式算,但是二者并不可以直接一起使用,所以最后还是要暴力去判断环的重复情况。利用 ( ext{next_permutation()}) 可以直接生成各自排列组合的情况,利用 ( ext{rotate()}) 可以将一个排列对应的环的所有情况求出,利用 ( ext{set}) 去一下重即可。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    int solve(int x,int y,int z)
    {
        string s=string(x,'a')+string(y,'b')+string(z,'c');
        set<string>st;
        do
        {
            string t1=s,t2=s;
            int n=x+y+z;
            for(int i=1;i<=n;i++)//圆圈枚举
            {
                rotate(t2.begin(),t2.begin()+1,t2.end());//中间的参数为下一个排列对应的开始位置
                t1=min(t1,t2);
            }
            st.insert(t1);
        }
        while(next_permutation(s.begin(),s.end()));
        return st.size();
    }
    int main()
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        ll ans=0;
        for(int i=0;i<=a;i++)
        {
            for(int j=0;j<=b;j++)
            {
                for(int k=0;k<=c;k++)
                {
                    if(i+j+k==0) continue;
                    ans+=solve(i,j,k);
                }
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    京东Java面试题(二)
    京东Java面试题(一)
    阿里java面试题
    Java垃圾回收机制
    MyBatis面试题
    Java IO流总结
    Spring中文文档
    Vue.js实战之组件之间的数据传递
    Vue.js实战之Vuex的入门教程
    Vue系列——在vue项目中使用jQuery及其第三方插件
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/14226190.html
Copyright © 2020-2023  润新知