zoukankan      html  css  js  c++  java
  • CSU 1027 Smallbox魔方

    CSU_1027

        对于一个立方体,一共有24种本质不同的旋转,整体上分为四类:

        ①静止不动;

        ②以某面与对面的中心的连线为轴,沿一个方向旋转90度、180度、270度;

        ③以某棱与对棱的中心的连线为轴,沿一个方向旋转180度;

        ④以某个顶点与对顶点的连线为轴,沿一个方向旋转60度、120度。

        对于每类都可以用组合数计算出不动方案的种数,然后应用一下burnside引理就可以得到最后的结果了。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 15010
    #define MOD 1000000007
    int N, M, a[10], b[10], ny[MAXD];
    long long exgcd(long long a, long long b, long long &x, long long &y)
    {
        if(b == 0)
            x = 1, y = 0;
        else
            exgcd(b, a % b, y, x), y -= x * (a / b);
    }
    void prepare()
    {
        int i;
        long long x, y;
        for(i = 1; i <= 15000; i ++)
        {
            exgcd(i, MOD, x, y);
            x = (x % MOD + MOD) % MOD;
            ny[i] = x;
        }
    }
    void init()
    {
        int i;
        scanf("%d", &N);
        M = 6 * N * N;
        for(i = 0; i < 6; i ++)
            scanf("%d", &a[i]);
    }
    long long comb(int n, int m)
    {
        int i;
        long long ans = 1;
        for(i = n - m + 1; i <= n; i ++)
            ans = ans * i % MOD;
        for(i = 2; i <= m; i ++)
            ans = ans * ny[i] % MOD;
        return ans;
    }
    long long calculate(int m)
    {
        int i, j, n = 0;
        long long ans = 1;
        for(i = 0; i < 6; i ++)
        {
            if(b[i] % m != 0)
                return 0;
            b[i] /= m;
            n += b[i];
        }
        for(i = 0; i < 6; i ++)
        {
            ans = ans * comb(n, b[i]) % MOD;
            n -= b[i];
        }
        return ans;
    }
    long long frotate()
    {
        int i, j;
        long long ans = 0;
        // 0
        memcpy(b, a, sizeof(a));
        ans = (ans + calculate(1)) % MOD;
        // 90 270
        if(N & 1)
        {
            for(i = 0; i < 6; i ++)
                for(j = 0; j < 6; j ++)
                {
                    memcpy(b, a, sizeof(a));
                    -- b[i], -- b[j];
                    if(b[i] < 0 || b[j] < 0)
                        continue;
                    ans = (ans + 6 * calculate(4)) % MOD;
                }
        }
        else
        {
            memcpy(b, a, sizeof(a));
            ans = (ans + 6 * calculate(4)) % MOD;
        }
        // 180
        if(N & 1)
        {
            for(i = 0; i < 6; i ++)
                for(j = 0; j < 6; j ++)
                {
                    memcpy(b, a, sizeof(a));
                    -- b[i], -- b[j];
                    if(b[i] < 0 || b[j] < 0)
                        continue;
                    ans = (ans + 3 * calculate(2)) % MOD;
                }
        }
        else
        {
            memcpy(b, a, sizeof(a));
            ans = (ans + 3 * calculate(2)) % MOD;
        }
        return ans;
    }
    long long erotate()
    {
        int i;
        long long ans = 0;
        // 180
        memcpy(b, a, sizeof(a));
        ans = (6 * calculate(2)) % MOD;
        return ans;
    }
    long long vrotate()
    {
        int i;
        long long ans = 0;
        // 60 120
        memcpy(b, a, sizeof(a));
        ans = (8 * calculate(3)) % MOD;
        return ans;
    }
    void solve()
    {
        long long ans = 0;
        ans = (ans + frotate()) % MOD;
        ans = (ans + erotate()) % MOD;
        ans = (ans + vrotate()) % MOD;
        ans = ans * ny[24] % MOD;
        printf("%lld\n", ans);
    }
    int main()
    {
        int t;
        prepare();
        scanf("%d", &t);
        while(t --)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    辨异 —— 冠词(定冠词、不定冠词、零冠词)
    辨异 —— 冠词(定冠词、不定冠词、零冠词)
    dot 语法全介绍
    dot 语法全介绍
    图像的简单认识
    图像的简单认识
    向量点乘(内积)和叉乘(外积、向量积)概念及几何意义解读
    图的重要性质
    Android下载文件提示文件不存在。。。 java.io.FileNotFoundException
    Java程序猿的JavaScript学习笔记(5——prototype和Object内置方法)
  • 原文地址:https://www.cnblogs.com/staginner/p/2511049.html
Copyright © 2011-2022 走看看