UVA 1030 模拟

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值