1. Title Description: Click to open the link
2. Problem-solving ideas: The subject requires re-coating as few faces as possible, making n cubes exactly the same. A problem that seems to be tricky. The first method to think of is violent search. But one of the first things to figure out is: how many different ways does a cube rotate? If we choose a face as the top, there are 6 kinds of selection method, then choose a face as the front, there are 4 kinds of selection method, at this time the cube "posture" is determined, according to the multiplication principle, there are 6*4=24 kind of posture (here with attitude refers to the rotation mode, a gesture is a kind of rotation).
Okay, so how do you create these 24 gestures next? We define a "standard gesture" in advance: the polygon with the number I is located in the cube of position I (the number of each face in the topic is 1~6, in order to facilitate processing, in the program numbering range to 0~5, the standard posture is the way of the problem). Then the other 23 gestures can be rotated by this standard gesture. For example, the "standard stance" with 3-4 axis, rotating to the left, then 1->5,5->6,6->,2->1. If we make p[i] represent the position where the face of the number I is rotated, then the standard gesture above can be represented as {5,1,3,4,6,2} after turning left. Thus, the idea of enumerating poses is determined: first enumerate a number as the top, and then see how it has several gestures. For example: Number 1 on the top: The standard attitude is turned up once, rotated 0~3 times on the left, the number 2 is the top: the standard attitude is rotated 1 times, up to 1 times, and then left to rotate the 0~3 times, and so on can get these 24 posture.
To facilitate debugging, here's a tip: Write a program that generates these 24 gestures independently, output these 24 gestures to a file, and copy them into the final program as a constant table. Place them all in the array dice24[24][6], Dice24[i][j] represents the position of the I pose number J.
The next violent search, then how to "violence"? The method here is to first enumerate each cube's posture (the first as a reference system, without rotation), and then for these 6 faces, select one of the most frequently occurring colors as "standard", and its different colors are re-applied. Thus, according to the multiplication principle is easy to know, at most only 24^3 kind of situation. The details of the subject are too much, here only the approximate enumeration of ideas, detailed details see the Code comment section.
3. Code:
(Generate code for 24 gestures)
#define _crt_secure_no_warnings #include <iostream> #include <algorithm> #include <string> #include <sstream> #include <set> #include <vector> #include <stack> #include <map> #include < queue> #include <deque> #include <cstdlib> #include <cstdio> #include <cstring> #include < cmath> #include <ctime> #include <functional>using namespace Std;int left[] = {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]];/ /equivalent mapping: I->p->t}void enumerate_permutation () {int p0[6] = {0, 1, 2, 3, 4, 5};p rintf ("int dice24[24][6]={\n"); t i = 0; I < 6; i++) {int p[6];memcpy (p, p0, sizeof (p0));//both start with the standard stance if (i = = 0) rot (up, p);//Enumerate the actions that turn I into the top side (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 (left, p); Rot (up, p);} if (i = = 5) {rot (left, p); Rot (left, p); Rot (up, p);}for (int j = 0; J < 4; j + +)//4 cases on the side {printf ("{%d,%d,%d,%d,%d,%d},\n", p[0], p[1], p[2], p[3]); Rot (left, p) ;}} printf ("};\n");} int main () {freopen ("T.txt", "w", stdout); Enumerate_permutation (); return 0;}
(Final program)
#define _crt_secure_no_warnings #include <iostream> #include <algorithm> #include <string> #include <sstream> #include <set> #include <vector> #include <stack> #include <map> #include < queue> #include <deque> #include <cstdlib> #include <cstdio> #include <cstring> #include < cmath> #include <ctime> #include <functional>using namespace Std;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},};//24 species posture A constant table, Dice24[i][j], which represents the position of the first face of the type I rotation attitude number J (Note the distinction between "number" and "position") #define N 4int N, Dice[n][6], Ans;//dice[i][j] represents the first cube, the color of the polygon numbered J Vector<string>names;int ID (const char*name)// Assign each color a id{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 r[n], color[n][6];//r[i] represents the pose number of the cube I, Color[i][j] represents the color of the polygon where the I-Cube is positioned J (Note that "position" is J, not "number" is j) void Check () {for (int i = 0; I < n;i++) for (int j = 0; J < 6; J + +) Color[i][dice24[r[i]][j]] = dice[i][j];//The position of J is dice24[i][j]int tot in gesture i = 0;//count the total number of faces that need to be re-painted for (int j = 0; J < 6; J + +)/enumerate each polygon {int cnt[n * 6];//cnt[i] to indicate the number of times the color I appears memset (CNT, 0, sizeof (CNT)); int m Axface = 0;for (int i = 0; i < n; i++)//Enumerates the colors of faces where each cube's position is J Maxface = Max (Maxface, ++cnt[color[i][j]);//statistics of the number of colors that occur most often tot + = n-maxface;//When the position is J, the number of times to be re-applied is N-maxface}ans = min (ans, tot);} void Dfs (int d)//uses DFS to enumerate the posture of each cube, at most only 24^3 case {if (d = = n) check ();//When the enumeration is complete, start to check how many faces need to be re-applied else for (int i = 0; i <; i++) {R [d] = I;dfs (d + 1);}} int main () {//freopen ("T.txt", "R", stdin), while (~SCANF ("%d", &amP;n) && N) {names.clear (); for (int i = 0, i < n;i++) for (int j = 0; J < 6; J + +) {char name[30];cin >> NA ME;DICE[I][J] = ID (name);} Ans = n * 6;r[0] = 0;dfs (1);p rintf ("%d\n", ans); return 0;}
Example 1.8 Color Cube UVa1352