链接:
刘汝佳书上的例题(训练指南P16),感觉这题很好,尤其是生成旋转序列的方法,这也是这题的重点。学习了。
#include<cstdio> #include<cstring> #include<map> #include<set> #include<string> using namespace std; map<string,int>color; int cube[5][6]; int now[5][6]; int n, ans; int p[7]; int cnt[25]; int dice24[24][6] = { 3,1,0,5,4,2, 1,2,0,5,3,4, 2,4,0,5,1,3, 4,3,0,5,2,1, 3,5,1,4,0,2, 5,2,1,4,3,0, 2,0,1,4,5,3, 0,3,1,4,2,5, 0,1,2,3,4,5, 1,5,2,3,0,4, 5,4,2,3,1,0, 4,0,2,3,5,1, 5,1,3,2,4,0, 1,0,3,2,5,4, 0,4,3,2,1,5, 4,5,3,2,0,1, 3,4,5,0,1,2, 4,2,5,0,3,1, 2,1,5,0,4,3, 1,3,5,0,2,4, 3,0,4,1,5,2, 0,2,4,1,3,5, 2,5,4,1,0,3, 5,3,4,1,2,0, }; int left[] = {1,5,2,3,0,4}; int up[] = {3,1,0,5,4,2}; // “旋转” void rot(int* T, int* p){ int q[6]; memcpy(q,p,sizeof(q)); for(int i=0; i<6; ++i) p[i] = q[T[i]]; } // 生成旋转序列用的 void func(){ 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(p0)); if(i==0) rot(up, p); if(i==1) { rot(left,p); rot(up, p); } if(i==3) { rot(up,p); rot(up, p); } if(i==4) { rot(left, p); rot(left,p); rot(up,p); } if(i==5) { rot(left, p); rot(left,p); rot(left,p); rot(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]); rot(left,p); } } printf("};\n"); } // dfs暴力答案 void dfs(int cur){ if(cur>=n){ int counter=0; for(int i=0; i<6; ++i) { memset(cnt, 0, sizeof(cnt)); int tmp=0; for(int j=0; j<n; ++j){ tmp = max(tmp, ++cnt[now[j][i]]); } counter += n-tmp; } ans = min(counter, ans); return; } for(int i=0; i<24; ++i){ for(int j=0; j<6; ++j) now[cur][j] = cube[cur][dice24[i][j]]; dfs(cur+1); } } int main(){ char c[30]; int idx; while(~scanf("%d", &n) && n){ idx=0; color.clear(); for(int i=0; i<n; ++i){ for(int j=0; j<6; ++j) { scanf("%s", c); if(color.find(c) == color.end()){ color[c] = ++idx; } cube[i][j] = color[c]; } } ans = 10000000; for(int i=0; i<6; ++i) now[0][i]=cube[0][i]; dfs(1); printf("%d\n", ans); } return 0; }