uva 11255 - Necklace(置换)

题目链接:uva 11255 - Necklace

题目大意:给定3种颜色的珠子个数,要求所有的珠子都用上的情况下有多少种不同的项链,旋转翻转视为同一种。

解题思路:等价类的计数,polya。

  • 旋转:有0,1,~ n-1步。
  • 翻转:考虑n为奇数偶数,奇数下,有n条对称轴(过一点)偶数时,有n/2条过两点,n/2条不过点。
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;
const int maxn = 40;

int N, col[3], u[3];
ll c[maxn+5][maxn+5];

void init () {
    for (int i = 0; i <= maxn; i++) {
        c[i][0] = c[i][i] = 1;
        for (int j = 1; j < i; j++)
            c[i][j] = c[i-1][j-1] + c[i-1][j];
    }
}

int gcd (int a, int b) {
    return b == 0 ? a : gcd (b, a % b);
}

ll solve (int k) {
    int n = 0;
    ll ret = 1;

    for (int i = 0; i < 3; i++) {
        if (u[i] % k)
            return 0;
        u[i] /= k;
        n += u[i];
    }

    for (int i = 0; i < 3; i++) {
        ret *= c[n][u[i]];
        n -= u[i];
    }
    return ret;
}

ll polya () {
    ll ret = 0;

    for (int i = 0; i < N; i++) {
        memcpy(u, col, sizeof(col));
        ret += solve(N/gcd(i, N));
    }

    if (N&1) {

        for (int i = 0; i < 3; i++) {
            if (col[i]) {
                memcpy(u, col, sizeof(col));
                u[i]--;
                ret += N * solve(2);
            }
        }
    } else {

        memcpy(u, col, sizeof(col));
        ret += N/2 * solve(2);

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (col[i] && col[j]) {
                    memcpy(u, col, sizeof(col));
                    u[i]--; u[j]--;
                    ret += N/2 * solve(2);
                }
            }
        }
    }
    return ret / 2 / N;
}

int main () {
    init();

    int cas;
    scanf("%d", &cas);
    while (cas--) {
        N = 0;
        for (int i = 0; i < 3; i++) {
            scanf("%d", &col[i]);
            N += col[i];
        }
        printf("%lld\n", polya());
    }
    return 0;
}

uva 11255 - Necklace(置换),布布扣,bubuko.com

时间: 2024-11-06 04:45:43

uva 11255 - Necklace(置换)的相关文章

UVA 11255 - Necklace(Ploya)

UVA 11255 - Necklace 题目链接 题意:一个链子,由三种颜色的珠子构成,现在给定三种颜色的珠子个数,求能组成多少种(旋转,翻转算同一种) 思路:利用ploya定理,然后分类讨论即可 代码: #include <cstdio> #include <cstring> typedef long long ll; const int N = 45; int t, a, b, c, n; ll C[N][N]; void getC() { for (int i = 0; i

uva 10601 - Cubes(置换)

题目链接:uva 10601 - Cubes 题目大意:有12根等长的小木棍,然后每根木棍,输入每根木棍颜色的编号,你的任务是统计出用它们拼出多少种不同的立方体,旋转之后完全相同的立方体被认定相同. 解题思路:polya,然后对应立方体有24种旋转: 不旋转(still):1种,循环长度为12 以对顶点为轴(rot_point):4组,循环长度为3 以对面中心为轴(rot_plane):3组,分别有90,180,270度旋转,分别对应循环长度3,2,3 以对边为轴(rot_edge):6组,除了

UVa 11330 (置换 循环的分解) Andy&#39;s Shoes

和UVa11077的分析很类似. 我们固定左脚的鞋子不动,然后将右脚的鞋子看做一个置换分解. 对于一个长度为l的循环节,要交换到正确位置至少要交换l-1次. 1 #include <cstdio> 2 #include <cstring> 3 #include <map> 4 using namespace std; 5 6 bool vis[10000 + 10]; 7 8 int main() 9 { 10 //freopen("in.txt",

UVA 11054 The Necklace 转化成欧拉回路

题意比较简单,给你n个项链碎片,每个碎片的两半各有一种颜色,最后要把这n个碎片串成一个项链,要求就是相邻碎片必须是同种颜色挨着. 看了下碎片总共有1000个,颜色有50种,瞬间觉得普通方法是无法在可控时间内做出来的,因为碎片到底放哪里以及是正着放还是反着放都是不可控的. 这个时候数学建模就真的好重要了,如果我们能把颜色作为节点,一个碎片就表示两个节点连了一条路,那其实就是走了一遍欧拉回路,就意味着项链做成了. 太叼了,这个思想真心不错...LRJ书上的提示,否则我还真是想不到可以这样. 不过还有

UVA 1016 - Silly Sort(置换分解+贪心)

UVA 1016 - Silly Sort 题目链接 题意:给定一个序列,数字都不同,每次可以交换两个数字,交换的代价为两数之和,要求出把这个序列变成递增最小代价 思路:利用置换的分解原理,可以把序列的每条循环单独考虑,对于每条循环而言,不断交换肯定每个数字至少会换到一次,再利用贪心的思想,如果每次拿循环中的最小值去置换,那么就是这个最小值会用长度-1次,而剩下的数字各一次,注意这里还有一种可能优的方法,就是先把整个序列中的最小值换到该循环中,等置换完再换出去,两种都考虑进来即可 代码: #in

UVA - 10733 The Colored Cubes (置换)

All 6 sides of a cube are to becoated with paint. Each side is is coated uniformly with one color. When a selectionof n different colors of paint is available, how many different cubes can youmake? Note that any two cubes are onlyto be called "differ

UVA 239 - Tempus et mobilius. Time and motion(置换周期)

UVA 239 - Tempus et mobilius. Time and motion 题目链接 题意:这题题意也是吊得飞起,看了老半天,大概是这样: 有一个放球的队列,和3个轨道(说白了就是栈),一个容纳5,1个12,1个12,每1分钟队列出一个小球,放入栈,如果放入5的满了,就把5的放回队列,头一个放入12的,如果12的满了,就把12的放回队列,头一个放入另一个12的栈,如果又满了,就全部放回队列(头一个最后放回),问多少天之后,队列中小球会回复原来的状态 思路:先是模拟求出一天的情况,

uva 239 - Tempus et mobilius. Time and motion(置换)

题目连接:uva 239 - Tempus et mobilius. Time and motion 题目大意:古代有一个计时器,由n个编号从1~n的球组成,然后有三个轨道,分别对应的是1分钟,5分钟,1小时,例如各个轨道都有一个球的时间为1小时6分钟.计时器的工作原理是每一分钟从球堆里滚出一个球到1分钟的轨道上(球堆是一个队列),特殊情况是1分钟的轨道上有了4个球,再进1个球的话就表示5分钟,所以这个球要滚到5分钟的轨道上,并且要将1分钟轨道上的球按照后进先出的顺序放回球堆的末尾. 对应的5分

uva 11330 - Andy&#39;s Shoes(置换)

题目链接:uva 11330 - Andy's Shoes 题目大意:小andy有很多鞋,穿完到处丢,后来他把所有鞋都放回鞋架排成一排,保证了鞋的左右交替,但是颜色混了.问说他至少移动多少次可以将鞋分类好. 解题思路:对应奇数位置为左鞋,偶数位置为右鞋,一双鞋只有一只左鞋和一只右鞋,保证不换左变鞋子,以左鞋的位置为基准换右边鞋子,对应右边鞋子的位置即为一个置换,将置换的循环分解为x个互不相干的循环,ans=n-x #include <cstdio> #include <cstring&g