uva10601 - Cubes

本文深入探讨了Burnside计数定理在离散数学中的应用,详细解释了置换群、等价关系及不动点的概念,并通过正方体旋转问题实例展示了定理的实际运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1542

Burnside计数定理

我想用离散数学的语言重新描述一下这个定理:
首先你有一个有限集合XXXfff是这个集合上的置换,gggXXXXXX的函数
定义一个置换群A=&lt;{f1,f2,...,fk},A=&lt;\{f_1,f_2,...,f_k\},A=<{f1,f2,...,fk},函数合成&gt;&gt;>
定义关系RRR,对于两个函数ga,gbg_a,g_bga,gb,如果ga∘fi=gbg_a\circ f_i=g_bgafi=gb,其中fi∈Af_i\in AfiA,则faRfbf_aRf_bfaRfb
不难证明RRR的自反性、传递性、对称性,因此RRR是等价关系
不动点:对于置换群中的一个置换fif_ifi,如果一个函数ggg满足g∘f=gg\circ f=ggf=g,就称gggfff的不动点
BurnsideBurnsideBurnside计数定理指出,对于一个集合S={g1,g2,...,gn}S=\{g_1,g_2,...,g_n\}S={g1,g2,...,gn},以RRR诱导出的等价关系来划分SSS,得到的等价类的数目是置换群中每个置换的不动点的个数的平均数

题解

正方体旋转这种冷门知识谁会知道啊qwq
先来构造置换群:

  • 不动置换,这个置换被拆成121212个环,每个环的大小为111
  • 以对面中心连线为轴旋转90∘90^\circ90270∘270^\circ270,这个置换被拆成333个环,大小都为444
  • 以对面中心连线为轴旋转180∘180^\circ180,这个置换被拆成666个环,大小都为222
  • 以对棱为的重点连线为轴旋转180∘180^\circ180,这个置换被拆成777个环,大小分别为1,1,2,2,2,2,21,1,2,2,2,2,21,1,2,2,2,2,2
  • 以体对角线为为轴旋转120∘120^\circ120240∘240^\circ240,这个置换被拆成444个环,每个大小为333

每个环内所有点的颜色都得是一样的
写一个爆搜计数就好了

代码

//等价类计数
#include <bits/stdc++.h>
#define maxn 110
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
int cnt, res[maxn], need[maxn];
int read(int x=0)
{
	int c, f=1;
	for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
	for(;isdigit(c);c=getchar())x=x*10+c-48;
	return f*x;
}
void dfs(int pos)
{
	int i;
	if(pos>need[0])
	{
		cnt++;
		return;
	}
	for(i=1;i<=6;i++)
	{
		if(res[i]>=need[pos])
		{
			res[i]-=need[pos];
			dfs(pos+1);
			res[i]+=need[pos];
		}
	}
}
int main()
{
	int i, T=read(), ans;
	while(T--)
	{	
		cl(res);
		for(i=1;i<=12;i++)res[read()]++;
		
		ans=0;
		
		cnt=0;
		need[0]=12;
		for(i=1;i<=12;i++)need[i]=1;
		dfs(1);
		ans+=cnt;
		
		cnt=0;
		need[0]=3;
		for(i=1;i<=3;i++)need[i]=4;
		dfs(1);
		ans+=cnt*6;
		
		cnt=0;
		need[0]=6;
		for(i=1;i<=6;i++)need[i]=2;
		dfs(1);
		ans+=cnt*3;
		
		cnt=0;
		need[0]=7;
		need[1]=need[2]=1;
		need[3]=need[4]=need[5]=need[6]=need[7]=2;
		dfs(1);
		ans+=cnt*6;
		
		cnt=0;
		need[0]=4;
		for(i=1;i<=4;i++)need[i]=3;
		dfs(1);
		ans+=cnt*8;
		
		printf("%d\n",ans/24);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值