UVA 1030
题目链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=245&problem=3471&mosmsg=Submission+received+with+ID+16504362
题意:
一个n*n*n的魔方由n*n*n个单位立方体组成。每个单位立方体六个面都涂上一种颜色。
现在给一个可能是残缺的立方体,给出立方体的六面视图,问最多有多少个单位立方体。
思路:
大白书1.1节例题6
自己想的时候第一思路穷讨论然后大模拟。然后觉得这个根据每个视图得出来当前格子和接下来要走到的格子可以做一个结构,结构里面存x,y,z,dx,dy,dz。然而这样还是很难处理。因为考虑到两个视图相交得出最“靠外面”的格子有着很多的分类讨论。
无奈看题解。
题解是4个for循环。
首先枚举的肯定是当前视图的哪一个格子(n^3),然后枚举是当前视图向后看的第几层。遇到已经判定为空格的点跳过,没赋值的点赋值,赋值过点判断是否合法。不合法就把格子去掉然后再走一次for循环。
for循环里面的变量下标值得好好推敲,因为调试了很久。
源码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <map>
using namespace std;
const int MAXN = 10 + 3;
int og[MAXN][MAXN][MAXN], ng[MAXN][MAXN][MAXN];
map<char,int>mm;
int n;
char op[MAXN * 2];
void get_data()
{
int cnt = 0;
for(int i = n ; i >= 1 ; i--){
for(int j = 1 ; j <= 6 ; j++){
scanf("%s", op);
for(int k = 1 ; k <= n ; k++){
char temp = op[k - 1];
if(temp == '.') og[j][i][k] = -1;
else{
if(mm[temp] == 0) mm[temp] = ++cnt;
og[j][i][k] = mm[temp];
}
}
}
}
}
void trans(int flag, int k, int j, int l, int &x, int &y, int &z)
{
if(flag == 1) x = j, y = l, z = k;
else if(flag == 2) x = l, y = n + 1 - j, z = k;
else if(flag == 3) x = n + 1 - j, y = n + 1 - l, z = k;
else if(flag == 4) x = n + 1 - l, y = j, z = k;
else if(flag == 5) x = j, y = k, z = n + 1 - l;
else if(flag == 6) x = j, y = n + 1 - k, z = l;
}
int main()
{
while(scanf("%d", &n) != EOF && n){
mm.clear();
get_data();
for(int i = 1 ; i <= n ; i++) for(int j = 1 ; j <= n ; j++) for(int k = 1 ; k <= n ; k++) ng[i][j][k] = 0;
for(int i = 1 ; i <= 6 ; i++){
for(int j = 1 ; j <= n ; j++){
for(int k = 1 ; k <= n ; k++){
if(og[i][j][k] == -1){
for(int l = 1 ; l <= n ; l++){
int x, y, z;
trans(i, j, k, l, x, y, z);
// if(x == 1 && y == 2 && z == 1){ printf("i = %d\n", i);printf("j = %d, k = %d, l = %d\n", j, k, l);}
ng[x][y][z] = -1;
}
}
}
}
}
// for(int i = 1 ; i <= n ; i++){
// for(int j = 1 ; j <= 6 ; j++){
// for(int k = 1 ; k <= n ; k++){
// if(og[j][i][k] == -1) printf("*");
// else printf("%d", og[j][i][k]);
// }
// printf(" ");
// }
// printf("\n");
// }
for(;;){
bool change = true;
for(int i = 1 ; i <= 6 ; i++){
for(int j = 1 ; j <= n ; j++){
for(int k = 1 ; k <= n ; k++){
if(og[i][j][k] == -1) continue;
for(int l = 1 ; l <= n ; l++){
int x, y, z;
trans(i, j, k, l, x, y, z);
if(ng[x][y][z] == -1) continue;
// printf("i = %d, j = %d, k = %d, l = %d\n", i, j, k, l);
// printf("x = %d, y = %d, z = %d\n", x, y, z);
// system("pause");
// if(x == 2 && y == 1 && z == 3){
// printf("i = %d, j = %d, k = %d, l = %d\n", i, j, k, l);
// printf("og[i][j][k] = %d\n", og[i][j][k]);
// printf("ng[x][y][z] = %d\n", ng[x][y][z]);
// system("pause");
// }
if(ng[x][y][z] == 0){
ng[x][y][z] = og[i][j][k];
// printf("first operation\n");
break;
}
if(ng[x][y][z] != og[i][j][k]) ng[x][y][z] = -1, change = false;
break;
}
}
}
}
if(change) break;
}
int ans = 0;
for(int i = 1 ; i <= n ; i++) for(int j = 1 ; j <= n ; j++) for(int k = 1 ; k <= n ; k++)
if(ng[i][j][k] != -1) ans++;
printf("Maximum weight: %d gram(s)\n", ans);
}
return 0;
}