uva 1352 Colored Cubes


There are several colored cubes. All of them are of the same size but they may be colored differently. Each face of these cubes has a single color. Colors of distinct faces of a cube may or may not be the same.

Two cubes are said to be identically colored

A cube and its mirror image are not necessarily identically colored. For example, two cubes shown in Figure 3 are not identically colored.

You can make a given set of cubes identically colored by repainting some of the faces, whatever colors the faces may have. In Figure 4, repainting four faces makes the three cubes identically colored and repainting fewer faces will never do.

Your task is to write a program to calculate the minimum number of faces that needs to be repainted for a given set of cubes to become identically colored.

Input 

The input is a sequence of datasets. A dataset consists of a header and a body appearing in this order. A header is a line containing one positive integern and the body following it consists of n lines. You can assume that 1uva 1352 Colored Cubes(枚举)_c++nuva 1352 Colored Cubes(枚举)_c++4

A dataset corresponds to a set of colored cubes. The integer n

color1 color2 color3 color4 color5 color6

corresponds to a cube colored as shown in Figure 6.

The end of the input is indicated by a line containing a single zero. It is not a dataset nor a part of a dataset.




uva 1352 Colored Cubes(枚举)_#include_03


Figure 2: Identically colored cubes



uva 1352 Colored Cubes(枚举)_uva_04


Figure 3: cubes that are not identically colored



uva 1352 Colored Cubes(枚举)_c++_05


Figure 4: An example of recoloring



uva 1352 Colored Cubes(枚举)_ide_06


Figure 5: Numbering of faces Figure 6: Coloring


Output 

For each dataset, output a line containing the minimum number of faces that need to be repainted to make the set of cub es identically colored.

Sample Input 


3 scarlet green blue yellow magenta cyan blue pink green magenta cyan lemon purple red blue yellow cyan green 2 red green blue yellow magenta cyan cyan green blue yellow magenta red 2 red green gray gray magenta cyan cyan green gray gray magenta red 2 red green blue yellow magenta cyan magenta red blue yellow cyan green 3 red green blue yellow magenta cyan cyan green blue yellow magenta red magenta red blue yellow cyan green 3 blue green green green green blue green blue blue green green green green green green green green sea-green 3 red yellow red yellow red yellow red red yellow yellow red yellow red red red red red red 4 violet violet salmon salmon salmon salmon violet salmon salmon salmon salmon violet violet violet salmon salmon violet violet violet violet violet violet salmon salmon 1 red green blue yellow magenta cyan 4 magenta pink red scarlet vermilion wine-red aquamarine blue cyan indigo sky-blue turquoise-blue blond cream chrome-yellow lemon olive yellow chrome-green emerald-green green olive vilidian sky-blue 0


Sample Output 


4 2 0 0 2 3 4 4 0 16



题目大意:给出n个正方体,然后n行表示每个正方体6个面的上色,问涂最少的面使得n正方体都相同(注意正方体是可以旋转的)。

解题思路:首先写出正方体有24个旋转方式,然后以第一个正方体为标准,枚举剩下n - 1个正方体的状态,然后计算最小值。具体见代码注释。



#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int dice[24][6] = {  //24种旋转方法
	{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},  
};  
char color[30][30];
int cnt, site[30][30], c[30], ans, n; 
int ID(char *str) {
	for (int i = 0; i < cnt; i++) {
		if (strcmp(color[i], str) == 0) return i; //与之前的颜色序号进行对比,若有相同颜色,返回该颜色的颜色序号
	}
	strcpy(color[cnt], str); 
	return cnt++;  //若之前不存在该颜色,创建并返回新的颜色序号
}
void check() {
	int v[30], sum = 0;
	for (int i = 0; i < 6; i++) {
		memset(v, 0, sizeof(v));
		int Max = 0;
		for (int j = 0; j < n; j++) {
			int temp = dice[c[j]][i]; //获取旋转过后处于第i序号面的面序号
			v[site[j][temp]]++; //统计各方块各面相同颜色数
			Max = max(Max, v[site[j][temp]]); //Max为各方块在第i序号面中相同颜色的个数
		}
		sum += n - Max; //sum为该旋转方法的颜色更新数
	}
	ans = min(sum, ans); //统计24种旋转方法中最小的颜色更新数
}
void DFS(int a) {
	if (a >= n) {
		check();
		return;
	}
	for (c[a] = 0; c[a] < 24; c[a]++) {  //枚举24种旋转情况
		DFS(a + 1);
	}
}
int main() {
	while (scanf("%d", &n) == 1, n) {
		cnt = 0;
		ans = 9999;
		memset(color, 0, sizeof(color));
		memset(c, 0, sizeof(c));
		char str[30];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < 6; j++) {
				scanf("%s", str);
				int num = ID(str);
				site[i][j] = num; //该数组存储的是第i个方块第j个序号面的颜色序号
			}
		}
		DFS(1);
		printf("%d\n", ans);
	}
	return 0;
}