问题
分析
这题的重点在于如何表示正方体的姿态,正方体的姿态可以有顶面和正面两个面唯一确定,关键是打表
按照书上的表示方法,1:正面,2右面,3顶面,4底面,5左面,6背面,可以用程序写出24种全部的姿态
标准姿态:{1 2 3 4 5 6}
向前翻:{3,2,6,1,5,4} 顶面变成正面,后面变成顶面
向左转:{5,1,3,4,6,2} 正面变成右面,顶面不变
比较最少多少个面使得正方体相同,所以先是枚举所有的组合,24^3(第一个正方体作为基准)种,然后再计算每种组合需要多少次涂色才能相同
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int maxn=15;
int up[6]={2,1,5,0,4,3},Left[6]={4,0,2,3,5,1};
void rotate(int T[6],int p[6]){
int temp[6];
memcpy(temp,p,sizeof(temp));
for(int i=0;i<6;++i){
p[i]=temp[T[i]];
}
}
void emurate_permutation(){
int p0[6]={0,1,2,3,4,5}; //标准姿态
printf("int dice={\n");
for(int i=0;i<6;++i){
int p[6];
memcpy(p,p0,sizeof(p0));
if(i==0) {rotate(up,p); rotate(up,p); rotate(up,p);}
if(i==1) {rotate(Left,p); rotate(up,p);}
if(i==3) {rotate(up,p); rotate(up,p);}
if(i==4) { rotate(Left,p); rotate(up,p); rotate(up,p); rotate(up,p);}
if(i==5) rotate(up,p);
for(int j=0;j<4;++j){
printf("{%d,%d,%d,%d,%d,%d},\n",p[0],p[1],p[2],p[3],p[4],p[5]);
rotate(Left,p);
}
}
printf("};\n");
}
int main(void){
emurate_permutation();
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
using namespace std;
const int maxn=4;
int dice24[24][6]={
{3,1,0,5,4,2},
{4,3,0,5,2,1},
{2,4,0,5,1,3},
{1,2,0,5,3,4},
{2,0,1,4,5,3},
{5,2,1,4,3,0},
{3,5,1,4,0,2},
{0,3,1,4,2,5},
{0,1,2,3,4,5},
{4,0,2,3,5,1},
{5,4,2,3,1,0},
{1,5,2,3,0,4},
{5,1,3,2,4,0},
{4,5,3,2,0,1},
{0,4,3,2,1,5},
{1,0,3,2,5,4},
{3,0,4,1,5,2},
{5,3,4,1,2,0},
{2,5,4,1,0,3},
{0,2,4,1,3,5},
{2,1,5,0,4,3},
{4,2,5,0,3,1},
{3,4,5,0,1,2},
{1,3,5,0,2,4},
};
int dice[maxn][6],n,color[maxn][6],d[maxn],ans;
map<string,int> str2id;
vector<string> id2str;
string s;
int ID(string &s){
if(str2id.count(s)) return str2id[s];
id2str.push_back(s);
return str2id[s]=id2str.size()-1;
}
int cal(){
for(int i=0;i<n;++i){
for(int j=0;j<6;++j){
color[i][j]=dice[i][dice24[d[i]][j]];
}
}
int tot=0,cnt[maxn*6];
for(int j=0;j<6;++j){
memset(cnt,0,sizeof(cnt));
int maxv=0;
for(int i=0;i<n;++i){
maxv=max(maxv,++cnt[color[i][j]]);
}
tot+=n-maxv;
}
ans=min(ans,tot);
return ans;
}
void dfs(int dep){
if(dep==n){
cal();
return;
}
for(int i=0;i<24;++i){
d[dep]=i;
dfs(dep+1);
}
}
int main(void){
while(scanf("%d",&n)==1 && n){
str2id.clear();
id2str.clear();
for(int i=0;i<n;++i){
for(int j=0;j<6;++j){
cin>>s;
dice[i][j]=ID(s);
}
}
ans=6*n;
d[0]=0; //0号正方体可以保持一个姿态不动
dfs(1);
printf("%d\n",ans);
}
}