题意:给出了n*n*n立方体的六视图,每个单位立方体的六面颜色相同,但不同单位立方体颜色不同,有些单位立方体缺失,字母代表不同颜色,'.'代表无颜色也就是没有任何正方体,问如果能形成这种六视图,剩余的单位立方体的数量最大是多少。
题解:这道题不容易想,用排除法,先让立方体是满的,然后根据给出的六视图将直接能看出是空缺的单位立方体先删除掉,然后根据此时的正方体再次由六视图判断,如果有矛盾的情况就可以继续删除单位正方体,直到完全符合六视图。这种删除方法可以用数学归纳法证明。
#include <stdio.h>
int n, x, y, z;
char cube[6][12][12], pos[12][12][12];
void get_pos(int k, int a, int b, int c) {
if (k == 0)
x = n - 1 - c, y = b, z = n - 1 - a;
else if (k == 1)
x = b, y = c, z = n - 1 - a;
else if (k == 2)
x = c, y = n - 1 - b, z = n - 1 - a;
else if (k == 3)
x = n - 1 - b, y = n - 1 - c, z = n - 1 - a;
else if (k == 4)
x = a, y = b, z = n - 1 - c;
else if (k == 5)
x = n - 1 - a, y = b, z = c;
}
int main() {
while (scanf("%d", &n) && n) {
for (int i = 0; i < n; i++)
for (int j = 0; j < 6; j++)
for (int k = 0; k < n; k++)
while (1) {
char c = getchar();
if (c == '.' || (c >= 'A' && c <= 'Z')) {
cube[j][i][k] = c;
break;
}
}
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
pos[i][j][k] = '#';
for (int i = 0; i < 6; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
if (cube[i][j][k] == '.') {
for (int l = 0; l < n; l++) {
get_pos(i, j, k, l);
pos[x][y][z] = '.';
}
}
int flag = 1;
while (flag) {
flag = 0;
for (int i = 0; i < 6; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
if (cube[i][j][k] != '.') {
for (int l = 0; l < n; l++) {
get_pos(i, j, k, l);
if (pos[x][y][z] == '.')
continue;
if (pos[x][y][z] == '#') {
pos[x][y][z] = cube[i][j][k];
break;
}
if (pos[x][y][z] == cube[i][j][k])
break;
pos[x][y][z] = '.';
flag = 1;
}
}
}
int res = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
if (pos[i][j][k] != '.')
res++;
printf("Maximum weight: %d gram(s)\n", res);
}
return 0;
}