0
点赞
收藏
分享

微信扫一扫

蓝桥杯——六面体染色

kmoon_b426 2022-07-27 阅读 67


正六面体染色

正六面体用4种颜色染色。

共有多少种不同的染色样式?

要考虑六面体可以任意旋转、翻转。

分析:六面体染色后任意旋转、翻转均判定为相同的染色方案,这点需要注意。

蓝桥杯——六面体染色_深搜

其实只有两种翻转方式,即水平翻转和竖直翻转。

创建一数组vis[333334],用于标记某方案是否已被访问。下标的每一个数位对应一个面的颜色编号。

因为是6个面,所以是个6数位;因为有四种颜色,所以每个数位为0~3的整数值

#include<iostream>
using namespace std;
#define f(a) for(a=0;a<4;a++)
bool vis[333334];
int sum;
//求某染色方案在vis的下标
int compute(int*);
//旋转正方体
void r(int,int,int,int,int,int);
int main() {
int a[6],t;
f(a[0])f(a[1])f(a[2])f(a[3])f(a[4])f(a[5]) {
t=compute(a); //求方案a对应vis的下标
if(vis[t]) continue;
sum++;
vis[t]=true;//标记方案t为已访问

//深搜,去除旋转后的重复方案
r(a[0],a[4],a[1],a[2],a[3],a[5]);
r(a[1],a[5],a[2],a[0],a[4],a[3]);
r(a[4],a[1],a[0],a[3],a[5],a[2]);
}
cout<<sum;
return 0;
}
//求染色方案a在vis的下标
int compute(int *a) {
return a[0]*100000+a[1]*10000+a[2]*1000+a[3]*100+a[4]*10+a[5];
}

//旋转正方体
void r(int a0,int a1,int a2,int a3,int a4,int a5) {
int a[6]= {a0,a1,a2,a3,a4,a5};
int t=compute(a);
if(vis[t]) return;
vis[t]=true;
//深搜
r(a[0],a[4],a[1],a[2],a[3],a[5]); //以“0”和“5”为轴旋转正方体
r(a[1],a[5],a[2],a[0],a[4],a[3]); //以“2”和“4”为轴旋转正方体
r(a[4],a[1],a[0],a[3],a[5],a[2]); //以“1”和“3”为轴旋转正方体
}

可直接用组合数学中的polya定理。

用n种颜色对正六面体进行染色的不同着色方案数为:

蓝桥杯——六面体染色_#include_02

#include<stdio.h>
#include<math.h>
int main()
{
int n=4;
int sum=(pow(n,6)+3*pow(n,4)+12*pow(n,3)+8*pow(n,2))/24;
printf("%d",sum);
return 0;
}


蓝桥杯——六面体染色_深搜_03


举报

相关推荐

0 条评论