Description
有很多个棱长为1的正方体货物整齐地堆在一堆。不过有一些是悬空的, 大概是粘上去的吧。。。
给出这些货物的相邻关系,求最小的长方体(或正方体)能装下这些货物的集装箱的体积,(集装箱棱长方向与这些正方体三个棱方向平行)。
Input
每组数据第一行一个n,表示有n个货物。1 <= n <= 1000
接下来n行每行6个数,第i行表示以棱方向为轴的x轴正负、y轴正负、z轴正负方向与第i个货物相邻的货物编号(i为1~n),0表示无该位置信息。
Output
如果描述出现矛盾或者无法确定货物是堆在一起的,输出"What?",否则输出集装箱体积。
Sample Input
3
0 0 0 0 3 2
0 0 0 0 1 0
0 0 0 0 0 1
Sample Output
3
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #define N 1005 #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define INF 0x3fffffff int x[N],y[N],z[N]; int p[N]; int n; void make_set() { for(int i=1;i<=n;i++) p[i]=i,x[i]=y[i]=z[i]=0; } int find_set(int i) { int pi=p[i]; if(i^p[i]) p[i]=find_set(p[i]); if(pi^p[i]) { x[i]+=x[pi]; y[i]+=y[pi]; z[i]+=z[pi]; } return p[i]; } void union_set(int i,int j,int dir,int d) { int pi,pj; pi=find_set(i); pj=find_set(j); p[pj]=pi; //dir为0 表示 i与j在x方向上相邻,d=1表示j在i右边 if(dir==0) { x[pj]=x[i]-x[j]+d; y[pj]=y[i]-y[j]; z[pj]=z[i]-z[j]; } else if(dir==1) { x[pj]=x[i]-x[j]; y[pj]=y[i]-y[j]+d; z[pj]=z[i]-z[j]; } else { x[pj]=x[i]-x[j]; y[pj]=y[i]-y[j]; z[pj]=z[i]-z[j]+d; } } int main() { int i,j; bool wa; while(~scanf("%d",&n)) { make_set(); wa=false; for(i=1;i<=n;i++) { for(int dir=0;dir<3;dir++) { for(int d=1;d>=-1;d-=2) { scanf("%d",&j); if(j==0) continue; if(find_set(i)^find_set(j)) union_set(i,j,dir,d); else { if(dir==0 && !(y[i]==y[j]&&z[i]==z[j]&&d==x[j]-x[i])) wa=true; if(dir==1 && !(x[i]==x[j]&&z[i]==z[j]&&d==y[j]-y[i])) wa=true; if(dir==2 && !(y[i]==y[j]&&x[i]==x[j]&&d==z[j]-z[i])) wa=true; } } } } for(i=2;!wa && i<=n;i++) if(find_set(i)!=find_set(1)) wa=true; int minx=INF,maxx=-INF; int miny=INF,maxy=-INF; int minz=INF,maxz=-INF; if(wa) puts("What?"); else { for(int i=1;i<=n;i++) { minx=MIN(minx,x[i]); maxx=MAX(maxx,x[i]); miny=MIN(miny,y[i]); maxy=MAX(maxy,y[i]); minz=MIN(minz,z[i]); maxz=MAX(maxz,z[i]); } printf("%d\n",(maxx-minx+1)*(maxy-miny+1)*(maxz-minz+1)); } } return 0; }