POJ1022 四维魔方(转载他人)

本文探讨了如何将粘合在一起的四维立方体组成的EE3产品,装入最小体积的四维平行六面体容器中。通过深度优先搜索算法确定立方体的位置关系并计算容器体积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Packing Unit 4D Cubes

Description




We usually think that there are three geometric dimensions; the fourth dimension is usually time. However, the Association for Customizing Machines (ACM) has to deal with four geometrical dimensions for their strange customer EE3 who needs to pack four dimensional products into perpendicular parallelepipeds before shipping them to the newly emerged market niche just on the outskirts of the Milky Way. 
Each of EE3 products consists of a number of unit 4D cubes that are glued together at their faces. A face of a 4D cube is a 3D cube and each 4D cube has 8 such faces. The picture on the left shows a 4D cube projected into a plane with the four principal, orthogonal axes shown. It takes a bit of effort to stretch our imagination and see the faces of a 4D cube in such a projection. The pictures below try to illustrate how the two faces along each of the four axes are situated in 4D. Again, using just the planar projection it is not so easy to illustrate and takes some effort to see. But we have done a good job, didn't we? 


 
Each EE3 product to be packed consists of a number of unit 4D cubes that are glued together along their faces which are 3D cubes. Your job is simple: find the minimal volume measured in the number of unit 4D cubes of a perpendicular parallelepiped (a 4D box) into which the product can be packed before shipping.

Input

The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by input data for each test case describing one EE3 product. The first line of each test case is an integer n (1 ≤ n ≤ 100) which is the number of unit 4D cubes used in the product. Next, there are n lines, each describing one unit cube and contains 9 nonnegative integer numbers. 
The first number, a positive integer, is the unique identifier of a cube and the remaining 8 numbers give the identities of neighbors of the cube listed in the following order: 
?the first two numbers are identifiers of the cubes glued to the opposing sides of the given cube along the x1 axis as seen looking in the direction of the x1 axis; 
?the next two numbers as above but for the x2 axis; 
?the next two numbers as above but for the x3 axis; 
?the next two numbers as above but for the x4 axis; 
If a cube does not have a neighbor glued to one of its faces we use 0 instead of a cube identifier. 
The problem is that the employees of ACM may produce inconsistent descriptions of EE3 products. There are two sources of such inconsistencies: 
?A consistent description must be symmetric, i.e. if cube x is glued to cube y at some face then cube y must be glued to cube x at the corresponding face along the same axis. The following description is inconsistent: 
3 0 0 1 0 0 0 0 0 
1 0 0 3 0 0 0 0 0 
?Any description must describe a single solid, i.e. there must be only one component in the product. Thus the following is inconsistent: 
1 2 0 0 0 0 0 0 0 
2 0 1 0 0 0 0 0 0 
3 0 0 4 0 0 0 0 0 
4 0 0 0 3 0 0 0 0

Output

There should be one output line per test case containing either the number of unit 4D cubes in the smallest 4D perpendicular parallelepiped oriented along the axes into which the product can be packed if the description is consistent, or the word Inconsistent, otherwise.

Sample Input

<span style="font-size: 18px;">1
9
1 2 3 4 5 6 7 8 9
2 0 1 0 0 0 0 0 0
3 1 0 0 0 0 0 0 0
4 0 0 0 1 0 0 0 0
5 0 0 1 0 0 0 0 0
6 0 0 0 0 0 1 0 0
7 0 0 0 0 1 0 0 0
8 0 0 0 0 0 0 0 1
9 0 0 0 0 0 0 1 0</span>

Sample Output

<span style="font-size: 18px;">81</span>

有个4D的物体(有四个轴线方向类似三维有三个轴线方向),它在每个轴线方向有2个面(它的面就是三维的。。一共就有八个面),然后有n个这样的物体,用胶水把它们对应的面粘起来,组成一个组合体(可以这么叫吧。。)求能装下这个组合体的容器(也是4D的)的最小体积。输入数据的第1行有一个数n,表示有n个样例接下来每个样例的第一行是m,表示有m个这样的单位物体共同组成组合体接下来有m行,每一行有九个数,第一个数是该单位物体的编号,后面8个数分别指的是8个面是否有用胶水粘以及和哪个物体粘。

思路:类比三维的,体积就是每个轴方向的长度相乘然后就是要统计每个轴方向有几个单位长度(有几个这样的单位物体),dfs。

#include <iostream>  
#include <cstdio>  
#include <cstring>  
#include <map>  
#include <algorithm>  
using namespace std;  
  
int flag,t,cnt,vis[105],a[105][8],sum1,sum2,sum3,sum4,pre;  
map<int,int> mp1;//从编号到下标的映射 
map<int,int> mp2;//从下标到编号的映射  
  
void dfs(int i)  
{  
    int j;  
    if(flag)return;  
    if(vis[i])return;  
    if(t!=8&&a[i][t]!=pre){flag=1;return;}  
    vis[i]=1;  
    cnt++;  
    for(j=0;j<8;j++)  
    {  
        if(flag)break;  
        if(a[i][j]!=0)  
        {  
            if(j%2==0)t=j+1;  
            else t=j-1;  
            if(j==1||j==0)sum1++;//统计面数  
            else if(j==2||j==3)sum2++;  
            else if(j==4||j==5)sum3++;  
            else if(j==6||j==7)sum4++;  
            pre=mp2[i];  
            dfs(mp1[a[i][j]]);  
        }  
    }  
}  
  
int main()  
{  
    int T,n,p,num,q;  
    scanf("%d",&T);  
    while(T--)  
    {  
        sum1=sum2=sum3=sum4=0;  
        flag=0;  
        t=8;  
        cnt=0;
        memset(vis,0,sizeof(vis));  
        scanf("%d",&n);  
        for(p=0;p<n;p++)  
        {  
            scanf("%d",&num);  
            mp1[num]=p;  
            mp2[p]=num;  
            for(q=0;q<8;q++)scanf("%d",&a[p][q]);  
        }  
        dfs(0);  
        if(flag||cnt<n)printf("Inconsistent\n");  
        else printf("%d\n",(sum1/2+1)*(sum2/2+1)*(sum3/2+1)*(sum4/2+1));  
    }  
    return 0;  
}  
另一个:

题目描述:有一个由n个四维的小立方体(四维的还能叫立方体?* v *)组成的产品(名字叫做EE3),小立方体之间互相用胶水粘在一起,现在需要一个程序判断EE3是否合格,如果合格计算EE3的体积(四维情况下还能叫体积么?@_@!!)。 
EE3合格的条件:所有的小立方体都连通,并且任意两个相邻的小立方体只公用一个维度,且在该维度上互相在对方的相反方向上。 
提醒:每一个小立方体都有8个面(因为四根坐标轴0.0)。 
输入格式:第一行一个整数t,表示输入有t组数据。 
接下来t组数据,每组数据第一行一个整数n,表示该组数据有n个小立方体。 
接下来是n行,每行9个数字,第一个数字是第n个小立方体的identifier,后面八个数字是与该小立方体相连的小立方体的identifier(!!!注意是identifier)。每两个数字是一条坐标轴的两个方向。 
输出格式:每组数据输出一行,一个整数或者”Inconsistent”,如果输入的n个小立方体无法组成一个合格的EE3就输出”Inconsistent”,否则输出一个整数,表示该EE3的体积。 
解题思路: 
从第一个输入的小立方体开始,bfs每一个与它连通的小立方体,如果有的小立方体没有被遍历到,说明Inconsistent,如果某两个小立方体不符合在他们共同的维度上方向相反的条件

#include <cstdio>
#define MAXN 1111

int main(int argc, char const *argv[])
{
    int t;
    for(scanf("%d", &t);t--;){
        int n;
        scanf("%d", &n);
        int id[MAXN];
        int map[MAXN][8]={0};
        for(int i=0; i<n; ++i){
            scanf("%d", &id[i]);
            for(int j=0; j<8; ++j){
                scanf("%d", &map[id[i]][j]);
            }
        }
        bool flag[MAXN]={false}, check=true;
        int  queue[MAXN], head=0, tail=0;
        queue[tail++] = id[0];
        flag[id[0]] = true;
        int maxh[MAXN][8]={0};
        while(head<tail){
            int idx=queue[head++];
            for(int l=0; l<8; ++l){
                int p=map[idx][l];
                if(p==0) { continue; }
                int ll=l%2?l-1:l+1;
                if(map[p][ll]!=idx){
                    check=false;
                    break;
                }
                if(flag[p]) { continue; }
                queue[tail++]=p;
                flag[p]=true;
                for(int j=0; j<8; ++j) { maxh[p][j]=maxh[idx][j]; }
                maxh[p][l]=maxh[idx][l]+1;
            }
            if(!check) { break; }
        }
        if(tail<n) { check=false; }
        if(!check){ printf("Inconsistent\n"); continue; }
        int ans=1;
        for(int j=0; j<4; ++j){
            int maxlen1=0, maxlen2=0;
            for(int i=0; i<n; ++i){
                int idx=id[i];
                maxlen1=maxh[idx][2*j]>maxlen1?maxh[idx][2*j]:maxlen1;
                maxlen2=maxh[idx][2*j+1]>maxlen2?maxh[idx][2*j+1]:maxlen2;
            }
            ans*=maxlen2+maxlen1+1;
        }
        printf("%d\n", ans);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值