比较恶心的一题,大白上已有详细解法,大致就是先写一个小程序,枚举正方体可以旋转出的24种形态。然后将第一个固定,第二三四分别枚举一个形态,24^3,然后统计所有正方块的上面,用出现次数最多的一个涂色,其余5个面同上记录涂色次数并不断更新
但最容易想到的一种错解是,枚举完形态后再枚举六个面分别的颜色,但颜色最多可能有24种,枚举每个面颜色就是24^6,再加上前面,24^9,复杂度太高,超时。
形态生成代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<queue> #include<algorithm> using namespace std; int lef[]={4,0,2,3,5,1}; int up[]={2,1,5,0,4,3}; void rot(int *T,int *p) { int q[6]; memcpy(q,p,sizeof q); for(int i=0;i<6;i++) p[i]=T[q[i]]; } void solve() { int p0[6]={0,1,2,3,4,5}; printf("int dice24[24][6]={\n"); for(int i=0;i<6;i++) { int p[6]; memcpy(p,p0,sizeof p); if(i==0)rot(up,p); if(i==1){rot(lef,p);rot(up,p);} if(i==3){rot(up,p);rot(up,p);} if(i==4){rot(lef,p);rot(lef,p);rot(lef,p);rot(up,p);} if(i==5){rot(lef,p);rot(lef,p);rot(up,p);} for(int j=0;j<4;j++) { printf("{%d,%d,%d,%d,%d,%d},",p[0],p[1],p[2],p[3],p[4],p[5]); rot(lef,p); } printf("\n"); } printf("};\n"); } int main() { solve(); return 0; }
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<queue> #include<algorithm> using namespace std; const int MAXN=4; int dice24[24][6]={ {2,1,5,0,4,3},{2,0,1,4,5,3},{2,4,0,5,1,3},{2,5,4,1,0,3}, {4,2,5,0,3,1},{5,2,1,4,3,0},{1,2,0,5,3,4},{0,2,4,1,3,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},{1,0,3,2,5,4},{0,4,3,2,1,5},{4,5,3,2,0,1}, {1,3,5,0,2,4},{0,3,1,4,2,5},{4,3,0,5,2,1},{5,3,4,1,2,0}, {3,4,5,0,1,2},{3,5,1,4,0,2},{3,1,0,5,4,2},{3,0,4,1,5,2}, }; int n,dice[MAXN][6],ans; vector<string>names; int ID(const char *name) { string s(name); int n=names.size(); for(int i=0;i<n;i++) if(names[i]==s)return i; names.push_back(s); return n; } int p[MAXN],color[MAXN][6]; void check() { for(int i=0;i<n;i++) for(int j=0;j<6;j++) color[i][dice24[p[i]][j]]=dice[i][j]; int tot=0; for(int j=0;j<6;j++) { int cnt[MAXN*6]; memset(cnt,0,sizeof cnt); int maxface=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++) { p[d]=i; dfs(d+1); } } int main() { while(~scanf("%d",&n)&&n) { names.clear(); for(int i=0;i<n;i++) for(int j=0;j<6;j++) { char name[30]; scanf("%s",name); dice[i][j]=ID(name); } ans=6*n; p[0]=0; dfs(1); printf("%d\n",ans); } return 0; }