Description
给定1212根木棍的颜色(用1…61…6表示),求可以拼成多少个不同的正方体。
Solution
发现一共有6×4=246×4=24种置换。
用fi,j,k,l,m,n,ofi,j,k,l,m,n,o表示第11种颜色有个,第22种颜色有个⋯⋯的方案数。直接dp出方案数,用BurnsideBurnside引理计算即可。
我居然智障地把所有置换都打表了?!其实完全直接把置换的不变元的数量手算出来
Source Code
/**************************************
* Au: Hany01
* Date: Feb 2nd, 2018
* Prob: UVa 10601 Cubes
* Email: hany01@foxmail.com
**************************************/
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef unsigned long long LL;
typedef pair<int, int> PII;
#define rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i)
#define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fd(i, j, k) for (i = (j); i >= (k); -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define fir first
#define sec second
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) ((int)(a).size())
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define debug(...) fprintf(stderr, __VA_ARGS__)
template <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
inline int read()
{
register int _, __; register char c_;
for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1;
for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
return _ * __;
}
inline void File()
{
#ifdef hany01
freopen("uva10601.in", "r", stdin);
freopen("uva10601.out", "w", stdout);
#endif
}
const int mp[24][12] =
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2, 3, 4, 1, 6, 7, 8, 5, 10, 11, 12, 9,
3, 4, 1, 2, 7, 8, 5, 6, 11, 12, 9, 10,
4, 1, 2, 3, 8, 5, 6, 7, 12, 9, 10, 11,
9, 6, 1, 5, 12, 10, 2, 4, 11, 7, 3, 8,
6, 1, 5, 9, 10, 2, 4, 12, 7, 3, 8, 11,
1, 5, 9, 6, 2, 4, 12, 10, 3, 8, 11, 7,
5, 9, 6, 1, 4, 12, 10, 2, 8, 11, 7, 3,
2, 6, 10, 7, 3, 1, 9, 11, 4, 5, 12, 8,
6, 10, 7, 2, 1, 9, 11, 3, 5, 12, 8, 4,
10, 7, 2, 6, 9, 11, 3, 1, 12, 8, 4, 5,
7, 2, 6, 10, 11, 3, 1, 9, 8, 4, 5, 12,
3, 7, 11, 8, 4, 2, 10, 12, 1, 6, 9, 5,
7, 11, 8, 3, 2, 10, 12, 4, 6, 9, 5, 1,
11, 8, 3, 7, 10, 12, 4, 2, 9, 5, 1, 6,
8, 3, 7, 11, 12, 4, 2, 10, 5, 1, 6, 9,
4, 8, 12, 5, 1, 3, 11, 9, 2, 7, 10, 6,
8, 12, 5, 4, 3, 11, 9, 1, 7, 10, 6, 2,
12, 5, 4, 8, 11, 9, 1, 3, 10, 6, 2, 7,
5, 4, 8, 12, 9, 1, 3, 11, 6, 2, 7, 10,
12, 11, 10, 9, 5, 8, 7, 6, 4, 3, 2, 1,
11, 10, 9, 12, 8, 7, 6, 5, 3, 2, 1, 4,
10, 9, 12, 11, 7, 6, 5, 8, 2, 1, 4, 3,
9, 12, 11, 10, 6, 5, 8, 7, 1, 4, 3, 2,
};
const int maxn = 14, maxc = 7;
LL Ans;
int f[maxn][maxn][maxn][maxn][maxn][maxn], o[maxc], co[maxc], t, vis[maxn], R[maxn], cnt;
inline LL Pow(LL a, LL b) {
LL Ans = 1;
for ( ; b; b >>= 1, a = a * a) if (b & 1) Ans *= a;
return Ans;
}
inline void DP()
{
int o[7];
Set(f, 0), f[0][0][0][0][0][0] = 1;
For(cur, 1, cnt)
Fd(o[1], co[1], 0) Fd(o[2], co[2], 0) Fd(o[3], co[3], 0)
Fd(o[4], co[4], 0) Fd(o[5], co[5], 0) Fd(o[6], co[6], 0) {
if (o[1] >= R[cur]) f[o[1]][o[2]][o[3]][o[4]][o[5]][o[6]] += f[o[1] - R[cur]][o[2]][o[3]][o[4]][o[5]][o[6]];
if (o[2] >= R[cur]) f[o[1]][o[2]][o[3]][o[4]][o[5]][o[6]] += f[o[1]][o[2] - R[cur]][o[3]][o[4]][o[5]][o[6]];
if (o[3] >= R[cur]) f[o[1]][o[2]][o[3]][o[4]][o[5]][o[6]] += f[o[1]][o[2]][o[3] - R[cur]][o[4]][o[5]][o[6]];
if (o[4] >= R[cur]) f[o[1]][o[2]][o[3]][o[4]][o[5]][o[6]] += f[o[1]][o[2]][o[3]][o[4] - R[cur]][o[5]][o[6]];
if (o[5] >= R[cur]) f[o[1]][o[2]][o[3]][o[4]][o[5]][o[6]] += f[o[1]][o[2]][o[3]][o[4]][o[5] - R[cur]][o[6]];
if (o[6] >= R[cur]) f[o[1]][o[2]][o[3]][o[4]][o[5]][o[6]] += f[o[1]][o[2]][o[3]][o[4]][o[5]][o[6] - R[cur]];
}
Ans += f[co[1]][co[2]][co[3]][co[4]][co[5]][co[6]];
}
int main()
{
File();
for (register int T = read(); T --; ) {
Set(co, 0), Ans = 0;
For(i, 1, 12) ++ co[read()];
rep(cur, 24) {
cnt = 0, Set(vis, 0);
rep(i, 12) if (!vis[t = i]) {
++ cnt, R[cnt] = 0;
while (!vis[t]) vis[t] = 1, t = mp[cur][t] - 1, ++ R[cnt];
}
DP();
}
Ans /= 24;
cout << Ans << endl;
}
return 0;
}