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组,除了两条边循环长度为1,其他为2.
#include <cstdio>
#include <cstring>
#include <algorithm>

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

int u[maxn+5], rod[maxn+5];
ll C[maxn+5][maxn+5];

void init () {
    memset(C, 0, sizeof(C));
    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];
    }
}

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

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

    for (int i = 0; i < 6; i++) {
        ret *= C[n][u[i]];
        n -= u[i];
    }
    //printf("%lld %lld!!\n", k, ret);
    return ret;
}

ll still () {
    memcpy(u, rod, sizeof(rod));
    return solve(1);
}

ll rot_point () {
    memcpy(u, rod, sizeof(rod));
    return 4 * 2 * solve(3);
}

ll rot_edge () {
    ll ret = 0;
    for (int i = 0; i < 6; i++) {
        for (int j = 0; j < 6; j++) {
            if (rod[i] && rod[j]) {
                memcpy(u, rod, sizeof(rod));
                u[i]--; u[j]--;
                ret += 6 * solve(2);
            }
        }
    }
    return ret;
}

ll rot_plane () {
    ll ret = 0;
    memcpy(u, rod, sizeof(rod));
    ret += solve(4) * 2 * 3;
    memcpy(u, rod, sizeof(rod));
    ret += solve(2) * 3;
    return ret;
}

inline ll polya () {
    return still() + rot_point() + rot_edge() + rot_plane();
}

int main () {
    init();

    int cas, x;
    scanf("%d", &cas);
    while (cas--) {

        memset(rod, 0, sizeof(rod));
        for (int i = 0; i < maxn; i++) {
            scanf("%d", &x);
            rod[x-1]++;
        }

        printf("%lld\n", polya() / 24);
    }
    return 0;
}

uva 10601 - Cubes(置换)

时间: 2024-12-07 05:37:09

uva 10601 - Cubes(置换)的相关文章

UVA - 10601 Cubes (组合+置换)

Description Problem B Cubes You are given 12 rods of equal length. Each of them is colored in certain color. Your task is to determine in how many different ways one can construct a cube using these rods as edges. Two cubes are considered equal if on

Uva 10601 Cubes 六维背包+burnside引理

题意:链接 方法:六维背包+burnside引理 解析: 挺好玩的一道burnside/polya题 结果我看到后既然这道题有颜色的限制,那么直接想起了card那道题.搞个背包什么的. 正方体有24种旋转方式. 面中心旋转 有 4 4 4 的置换 *3(90°) 有 2 2 2 2 2 2 的置换 *3(180°) 有 4 4 4 的置换 *3(90°) 棱中心旋转 有 1 1 2 2 2 2 的置换 *6 点对称旋转 有 3 3 3 3 的置换 *4 接下来呢? 怎么确定不变的置换的个数 对于

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

10601 - Cubes(Ploya)

UVA 10601 - Cubes 题目链接 题意:给定正方体12条棱的颜色,要求用这些棱能组成多少不同的正方体 思路:利用ploya定理去求解,分类讨论,正方体一共24种旋转.相应的旋转方式有4种: 1.不动 2.沿两面中点连线旋转 3.沿对顶点连线旋转 4.沿两棱中点连线旋转 简单推算出每种情况相应的循环组数.在加上组合数学去进行选择颜色求解.注意第4种情况中,有两条棱和其它的循环长度是不同的,能够枚举然后扣掉讨论. 代码: #include <stdio.h> #include <

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 s

组合数学(P&#243;lya计数原理):UvaOJ 10601 Cubes

Cubes You are given 12 rods of equal length. Each of them is colored in certain color. Your task is to determine in how many different ways one can construct a cube using these rods as edges. Two cubes are considered equal if one of them could be rot

UVa 11428 - Cubes

题目:给定一个正整数N求出满足N = x^3 - y^3的y最小的正整数对(x,y). 分析:数论,分治. x^3 - y^3 = (x-y)(x^2 + xy + y^2): 因为,x.y都是正整数,且x > y,则x^3 - y^3 > (x-y)(3y^3): 因为N是1~10000(x-y)与(x^2 + xy + y^2)都是1~10000内的整数: 所以,0 ≤ y ≤ 60,然后二分整数区间(y,y+10000)求x即可. 说明:怎么都是数论(⊙_⊙). #include <

UVA 10733 - The Colored Cubes(Ploya)

UVA 10733 - The Colored Cubes 题目链接 题意:一个立方体.n种颜色,问能涂成多少不同立方体 思路:Ploya求解,正方体相应24种不同旋转一一计算出循环个数就可以.和 UVA 10601 - Cubes这题类似 代码: #include <stdio.h> #include <string.h> unsigned long long n; int main() { while (~scanf("%llu", &n) &

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",