题意:在空间内有多个长方体,有一系列关系,分别是 A 的所有点的 x 坐标都比 B 的所有点的 x 坐标小, A 的所有点的 y 坐标都比 B 的所有点的 y 坐标小, A 的所有点的 z 坐标都比 B 的所有点的 z 坐标小,或者是 A 和 B有体积相交。要求给出一个符合上述关系的各个长方体,输出它们主对角线上的两点坐标。
将每个长方体的 x 、 y 、 z 作为点。每个长方体有两个 x 点(x1为值小的点,x2为值大的点),两个 y 点,两个 z 点,他们之间的关系是用边表示, e(u,v) 表示 u 的值小于 v 的值,对于每个长方体的每一维的两点可以先建边,然后两长方体的坐标大小比较就是用坐标小的长方体的大值点(A 的 x2)向坐标大的长方体的小值点(B 的 x1)建边,而体积有相交则是两长方体的小值点向对方的大值点建边(A 的 x1 向 B 的 x2 ;B 的 x1 向 A 的 x2);然后对 x、y、z 分别求一遍拓扑序,再随意从小到大分配值就行了。
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 const int maxn=1005*2; 6 const int maxm=110005; 7 8 int id[3][maxn],n; 9 int num[3][maxn]; 10 int head[3][maxn],point[3][maxm],nxt[3][maxm],size[3]; 11 char s[5]; 12 13 void add(int a,int b,int c){ 14 point[c][size[c]]=b; 15 nxt[c][size[c]]=head[c][a]; 16 head[c][a]=size[c]++; 17 id[c][b]++; 18 } 19 20 bool topo(int c){ 21 queue<int>q; 22 for(int i=1;i<=2*n;++i)if(!id[c][i])q.push(i); 23 int cnt=0; 24 while(!q.empty()){ 25 int u=q.front(); 26 q.pop(); 27 num[c][u]=++cnt; 28 for(int i=head[c][u];~i;i=nxt[c][i]){ 29 int j=point[c][i]; 30 id[c][j]--; 31 if(!id[c][j])q.push(j); 32 } 33 } 34 if(cnt==2*n)return 1; 35 return 0; 36 } 37 38 int main(){ 39 int cnt=0,m; 40 while(scanf("%d%d",&n,&m)!=EOF&&n+m){ 41 memset(head,-1,sizeof(head)); 42 memset(size,0,sizeof(size)); 43 memset(id,0,sizeof(id)); 44 for(int i=1;i<=n;++i){ 45 add(2*i-1,2*i,0); 46 add(2*i-1,2*i,1); 47 add(2*i-1,2*i,2); 48 } 49 while(m--){ 50 int a,b; 51 scanf("%s%d%d",s,&a,&b); 52 if(s[0]==‘X‘)add(2*a,2*b-1,0); 53 else if(s[0]==‘Y‘)add(2*a,2*b-1,1); 54 else if(s[0]==‘Z‘)add(2*a,2*b-1,2); 55 else if(s[0]==‘I‘){ 56 add(2*a-1,2*b,0); 57 add(2*a-1,2*b,1); 58 add(2*a-1,2*b,2); 59 add(2*b-1,2*a,0); 60 add(2*b-1,2*a,1); 61 add(2*b-1,2*a,2); 62 } 63 } 64 printf("Case %d: ",++cnt); 65 if(!topo(0))printf("IMPOSSIBLE\n"); 66 else if(!topo(1))printf("IMPOSSIBLE\n"); 67 else if(!topo(2))printf("IMPOSSIBLE\n"); 68 else{ 69 printf("POSSIBLE\n"); 70 for(int i=1;i<=n;++i){ 71 printf("%d %d %d %d %d %d\n",num[0][2*i-1],num[1][2*i-1],num[2][2*i-1],num[0][2*i],num[1][2*i],num[2][2*i]); 72 } 73 } 74 printf("\n"); 75 } 76 return 0; 77 }
时间: 2024-10-13 20:57:55