Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 876 Accepted Submission(s): 313
Special Judge
Problem Description
There are n boxes C1, C2, ..., Cn in 3Dspace. The edges of the boxes are parallel to the x, y or z-axis. We providesome relations of the boxes, and your task is to construct a set of boxessatisfying all these relations.
There are four kinds of relations (1 <=i,j <= n, i is different from j):
I i j: The intersection volume of Ci and Cjis positive.
X i j: The intersection volume is zero, andany point inside Ci has smaller x-coordinate than any point inside Cj.
Y i j: The intersection volume is zero, andany point inside Ci has smaller y-coordinate than any point inside Cj.
Z i j: The intersection volume is zero, andany point inside Ci has smaller z-coordinate than any point inside Cj.
.
Input
There will be at most 30 test cases. Eachcase begins with a line containing two integers n (1 <= n <= 1,000) and R(0 <= R <= 100,000), the number of boxes and the number of relations.Each of the following R lines describes a relation, written in the formatabove. The last test case is followed by n=R=0, which should not be processed.
Output
For each test case, print the case numberand either the word POSSIBLE or IMPOSSIBLE. If it's possible to construct theset of boxes, the i-th line of the following n lines contains six integers x1,y1, z1, x2, y2, z2, that means the i-th box is the set of points (x,y,z)satisfying x1 <= x <= x2, y1 <= y <= y2, z1 <= z <= z2. Theabsolute values of x1, y1, z1, x2, y2, z2 should not exceed 1,000,000.
Print a blank line after the output of eachtest case.
Sample Input
3 2
I 1 2
X 2 3
3 3
Z 1 2
Z 2 3
Z 3 1
1 0
0 0
Sample Output
Case 1: POSSIBLE
0 0 0 2 2 2
1 1 1 3 3 3
8 8 8 9 9 9
Case 2: IMPOSSIBLE
Case 3: POSSIBLE
0 0 0 1 1 1
Source
2009 Asia Wuhan Regional Contest Hosted byWuhan University
题解:
这道题是一道很好的题,在3D的空间中,长方体i在每一维看成是两个点,如在x轴上,长方体i的两个点是i和i+n(i表示左边的点,i+n表示右边的点,还未知道在x轴上的位置)。这道题给出了偏序关系,这个关系是小于关系。
1.I,两个长方体x、y相交,在每个轴上都有x < y+n, y < x+n;
2.X,两个长方体在X轴上,长方体x的两个顶点都小于长方体的最左的顶点,即x+n < y;
3.Y,在y轴上有x+n 4.Z,在Z轴上有x+n 根据现有的偏序关系,用inx[],iny[],inz[]表示在特定轴上某个点的入度,即在现有条件下,某点比多少点大。而用vector vx[],vy[],vz[],记录在特定轴上某点的出度的值,即在现有条件下比哪些点小,根据上面的偏序条件记录后,进行拓扑排序,最后能将某轴上1到2*n个顶点拓扑完的,说明在该轴上,满足条件。 源代码: #include #include #include #include #include #define MAX 2050 using namespace std; int inx[MAX],iny[MAX],inz[MAX]; vector<int> vx[MAX],vy[MAX],vz[MAX]; int ansx[MAX],ansy[MAX],ansz[MAX]; int n,m; void init() { memset(inx,0,sizeof(inx)); memset(iny,0,sizeof(iny)); memset(inz,0,sizeof(inz)); for(int i = 1;i <= 2*n;i++) { vx[i].clear(); vy[i].clear(); vz[i].clear(); } for(int i = 1;i <= n;i++) { vx[i].push_back(i+n); inx[i+n]++; vy[i].push_back(i+n); iny[i+n]++; vz[i].push_back(i+n); inz[i+n]++; } } bool topologicalsort(int*in,vector<int> v[],int *ans) { intnum = 0; queue<int>q; for(int i = 1;i <= 2*n;i++) { if(!in[i]) q.push(i); } while(!q.empty()) { intx = q.front(); q.pop(); ans[x] = num++; for(int i = 0;i < v[x].size();i++) { intf = v[x][i]; in[f]--; if(!in[f]) q.push(f); } } if(num== 2*n) returntrue; else returnfalse; } int main() { intcount = 0; charc[5]; intx,y; while(scanf("%d%d",&n,&m) != EOF &&n + m) { init(); for(int k = 0;k < m;k++) { scanf("%s%d%d",c,&x,&y); if(c[0]== 'I') { vx[x].push_back(y+n); inx[y+n]++; vx[y].push_back(x+n); inx[x+n]++; vy[x].push_back(y+n); iny[y+n]++; vy[y].push_back(x+n); iny[x+n]++; vz[x].push_back(y+n); inz[y+n]++; vz[y].push_back(x+n); inz[x+n]++; } elseif(c[0] == 'X') { vx[x+n].push_back(y); inx[y]++; } elseif(c[0] == 'Y') { vy[x+n].push_back(y); iny[y]++; } elseif(c[0] == 'Z') { vz[x+n].push_back(y); inz[y]++; } } intflag = 1; if(!topologicalsort(inx,vx,ansx)){flag = 0;} if(!topologicalsort(iny,vy,ansy)){flag = 0;} if(!topologicalsort(inz,vz,ansz)){flag = 0;} count++; if(flag) { cout << "Case " << count <<": POSSIBLE" < for(int i = 1;i <= n;i++) cout<< ansx[i]<<" " < << ansx[i+n]<<" "< cout << endl; } else { cout << "Case "< } } return0; }