view表示6面的视图,pos表示还原后的立体图。
做两次初始化:
首先将所有能看穿的图(‘.’)在所有深度上一定没有小方块。
另外如果两个视图对应同一个坐标小方块且颜色不同则小方块一定不存在。
然后统计非空的小方块个数即可。
#include <cstdio>
const int maxn = 10;
int n;
char pos[maxn][maxn][maxn];
char view[6][maxn][maxn];
char read_char() {
char ch;
for ( ; ; ) {
ch = getchar();
if ((ch >= 'A' && ch <= 'Z') || ch == '.') {
return ch;
}
}
}
//获得单位立方体在原立方体内的坐标
void get(int k, int i, int j, int len, int &x, int &y, int &z) {
if (k == 0) {
x = len;
y = j;
z = i;
}
if (k == 1) {
x = n - 1 - j;
y = len;
z = i;
}
if (k == 2) {
x = n - 1 - len;
y = n - 1 - j;
z = i;
}
if (k == 3) {
x = j;
y = n - 1 - len;
z = i;
}
if (k == 4) {
x = n - 1 - i;
y = j;
z = len;
}
if (k == 5) {
x = i;
y = j;
z = n - 1 - len;
}
}
int main(int argc, char const *argv[]) {
while (scanf("%d", &n) == 1 && n) {
for (int i = 0; i < n; i++) {
for (int k = 0; k < 6; k++) {
for (int j = 0; j < n; j++) {
view[k][i][j] = read_char();
}
}
}
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 k = 0; k < 6; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (view[k][i][j] == '.') {
for (int p = 0; p < n; p++) {
int x, y, z;
get(k, i, j, p, x, y, z);
pos[x][y][z] = '.';
}
}
}
}
}
for ( ; ; ) {
bool done = true;
for (int k = 0; k < 6; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (view[k][i][j] != '.') {
for (int p = 0; p < n; p++) {
int x, y, z;
get(k, i, j, p, x, y, z);
if (pos[x][y][z] == '.') {
continue;
}
if (pos[x][y][z] == '#') {
pos[x][y][z] = view[k][i][j];
break;
}
if (pos[x][y][z] == view[k][i][j]) {
break;
}
//如果对应的颜色不同那么格子一定不存在
pos[x][y][z] = '.';
done = false;
}
}
}
}
}
if (done) {
break;
}
}
int ans = 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] != '.') {
ans++;
}
}
}
}
printf("Maximum weight: %d gram(s)\n", ans);
}
return 0;
}