描述
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?
我们通常认为有三个几何维度,第四个维度通常是时间。然而,定制机械协会(ACM)必须为他们的奇怪客户 EE3处理四个几何尺寸,他们需要将四维产品装入垂直的平行六面体中,然后将它们运送到银河系外围新出现的市场利基。每一个 EE3产品由一些单位4D 立方体是胶合在一起,在他们的脸。一个4D 立方体的面是一个3D 立方体,每个4D 立方体有8个这样的面。左边的图片显示了一个4D 立方体投影到一个平面上,四个主要的正交轴如图所示。它需要一点努力来拓展我们的想象力,并在这样的投影中看到一个4D 立方体的面。下面的图片试图说明两个面沿着四个轴的每一个是如何在4D 位置。同样,仅仅使用平面投影并不那么容易说明,而且需要一些努力才能看到。但我们做得很好,不是吗?
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.
每个要包装的 EE3产品包括一些单位4D 立方体是胶合在一起的沿着他们的面是3D 立方体。你的工作很简单: 找到一个垂直平行六面体(一个4D 盒子)的单位4D 立方体的数量测量的最小体积的产品可以包装在运输之前。
输入
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:
输入文件的第一行包含一个单一的整数 t (1≤ t ≤10) ,测试用例的数量,然后是描述一个 EE3产品的每个测试用例的输入数据。每个测试用例的第一行是一个整数 n (1≤ n ≤100) ,这是产品中使用的单元4D 立方体的数目。接下来,有 n 行,每行描述一个单位立方体,包含9个非负整数。第一个数字是一个正整数,它是一个立方体的唯一标识符,剩下的8个数字按照以下顺序给出了立方体的相邻数字的恒等式: 前两个数字是沿着 x1轴粘在给定立方体的相对边上的立方体的标识符,如果沿着 x1轴的方向看,接下来的两个数字是上面的但是是 x2轴的,接下来的两个数字是上面的但是是 x3轴的,接下来的两个数字是上面的但是是 x4轴的,如果一个立方体没有相邻的立方体粘在它的一个面上,我们用0代替立方体的标识符。问题是 ACM 的员工可能会对 EE3产品产生不一致的描述。这种不一致有两个来源: 一致的描述必须是对称的,即如果立方体 x 在某个面上粘到立方体 y 上,那么立方体 y 必须沿着同一轴线粘到相应面上的立方体 x 上。以下描述不一致:
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
输出
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.
每个测试用例应该有一个输出行,其中包含最小的4D 垂直平行六面体中的单元4D 立方体的数量,如果描述一致,则沿着产品可以包装的轴线方向排列,否则包含“不一致”这个词。
样例输入
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
样例输出
81
来源
Tehran 2002, First Iran Nationwide Internet Programming Contest
分析
题目看上去有点高科技呵,先搞懂它在讲什么:
1.第一行表示样例数目。每个样例的第一行整数n表示样例中含有的物体数目,其后n行描述n个物体。
2.描述一个物体用一行,一行包含9个整数。第一个表示该物体的编号(相当于名字)。剩下的8个数字2个一组,共四组。
3.每一组数字表示该物体在一个方向上的前后邻居情况。(如果一个物体是二维平面的,我们认为它有x,y两个坐标轴方向。如果物体是三维的,我们认为它有x,y,z三个方向。本题中物体是四位的,用x,y,z,k代表它的四个方向)。
4.每一组中的第一个数表示这一方向上当前物体前面那个物体的编号。若当前物体的前面没有物体,则这个数为0.每一组中的第二个数表示这一方向上当前物体后面那个物体的编号,不存在则为0。
5.例如样例第三行:1 (2 3) (4 5) (6 7) (8 9) 。
含义如下:
当前物体编号为1;
在x方向上,前面物体编号为2,后面物体编号为3;
在y方向上,前面物体编号为4,后面物体编号为5;
······
7.所给数据有 合法/不合法 两种情况。数据合法的要求有两个:
1)在某方向上,物体A 在 物体B 的前面,那么 物体B 必须在 物体A 同方向的后面。乍看很费解,结合数
据清楚了。拿样例来说,1号物体的描述中,第二个数字是2 ,表示 2号 在 1号 x方向的前面。那么描
述 2号 物体时,表示 x轴 后面的数字必须是 1 ,即第三个数字是1。
2)给出的n个物体最终要连接成一个整体。(两物体在某一方向相邻,就认为它们连接起来了)。这个可
以测试连通性解决。
8.若数据 不合法 ,输出Inconsistent。若数据合法,则需要输出 该整体 的 外接立方体(四维的)的体积。
9.关于体积的求解:当我们求三维立方体的体积时,就是把x,y,z三个方向上的长度乘起来。对于本题中的四维立方体,只需要把x,y,z,k四个轴方向上的最大长度乘起来就可以了。每一个物体在四个方向的长度都是1.
意思差不多是这样,解题思路如下:
总体上利用深度优先搜索,从任意一个物体出发,看看是否能够遍历全部n个物体。若能,则满足第二个合法条件。
在遍历的同时检查第一个合法条件。例如:从 物体A 出发进入 物体B 的瞬间,检查 物体B 描述数据的对应位置是不是 物体A 的编号,如果是则进入B,否则直接返回 数据非法标志。
在遍历的同时还可以确定 外接立方体 在四个方向上的长度。任意挑选的第一个物体坐标为(0,0,0,0,),开两个数组up[4],down[4],分别记录在四个方向上的 最大坐标值和最小坐标值。若搜索到的第二个物体在当前物体x方向的前面,则它的坐标为(1,0,0,0),若在后面则是(-1,0,0,0)。即时比较更新up,down两个数组的值,则遍历结束后up-down就是所需四个方向的长度,乘起来就是答案。
代码
#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;
}
给个赞和关注吧