本题旋转方法很特别,先确定右旋和上旋,则每个面朝上都可以通过这两种操作实现;
再者,是暴力的角度,要从最优解出发,肯定可以确定的是每个立方体都为24种旋转方案中的一种;
则不如取第一个 只采用 24种旋转方式中的一种,然后枚举其他立方体的旋转方式,然后既然状态确定的情况下,就好统计了,每个面取n个立方体出现最多的内个颜色;
最坏复杂度 4 * 24^4; 一百万左右;
#include <cstdio> #include <cstring> #include <vector> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 4; int Right[] = {4,0,2,3,5,1}; int up[] = {3,1,0,5,4,2}; void rotate(int* A,int* B){ int C[6]; memcpy(C,B,sizeof(C)); for(int i=0;i<6;i++){ B[i] = C[A[i]]; } } int dice[24][6]; void init(){ int p0[] = {0,1,2,3,4,5}; for(int i=0;i<=6;i++){ int temp[6]; memcpy(temp,p0,sizeof(temp)); if(i==0) rotate(up,temp); if(i==1) {rotate(Right,temp); rotate(up,temp); rotate(up,temp); rotate(up,temp);} if(i==3) {rotate(up,temp); rotate(up,temp);} if(i==4) {rotate(Right,temp); rotate(up,temp);} if(i==5) {rotate(up,temp); rotate(up,temp); rotate(up,temp);} for(int j=0;j<4;j++){ rotate(Right,temp); for(int k=0;k<6;k++) dice[i*4+j][k] = temp[k]; } } } int ans,r[maxn],yuan[maxn][6],color[maxn][6],n; void check(){ for(int i=0;i<n;i++) for(int j=0;j<6;j++){ color[i][j] = yuan[i][dice[r[i]][j]]; } int tot=0; for(int j=0;j<6;j++){ int maxface = 0; int cnt[maxn*6]={0}; for(int i=0;i<n;i++){ maxface=max(maxface,++cnt[color[i][j]]); } tot+=n-maxface; } ans=min(ans,tot); } void dfs(int d){ if(d==n){ check(); return ; } for(int i=0;i<24;i++){ r[d] = i; dfs(d+1); } } vector<string> names; int ID(char* str){ string s(str); for(int i=0;i<names.size();i++){ if(names[i]==s) return i; } names.push_back(s); return names.size()-1; } char str[1000]; int main() { init(); while(scanf("%d",&n)==1 && n){ names.clear(); for(int i=0;i<n;i++){ for(int j=0;j<6;j++){ scanf("%s",str); yuan[i][j] = ID(str); } } r[0] = 0; ans = n*6; dfs(1); printf("%d\n",ans); } return 0; }