UVA12171-Sculpture(离散化+floodfill)

Posted npugen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA12171-Sculpture(离散化+floodfill)相关的知识,希望对你有一定的参考价值。

Problem UVA12171-Sculpture

Accept: 196  Submit: 1152

Time Limit: 3000 mSec

技术分享图片 Problem Description

 

Imagine a box, made of copper plate. Imagine a second one, intersecting the rst one, and several others, intersecting each other (or not). That is how the sculptor Oto Boxing constructs his sculptures. In fact he does not construct that much, he only makes the design; the actual construction is contracted out to a construction company. For the calculation of the costs of construction the company needs to know the total area of copper plate involved. Parts of a box that are hidden in another box are not realized in copper, of course. (Copper is quite expensive, and prices are rising.) After construction, the total construction is plunged into a bath of chemicals. To prevent this bath from running over, the construction company wants to know the total volume of the construction. Given that a construction is a collection of boxes, you are asked to calculate the area and the volume of the construction. Some of Oto’s designs are connected, others are not. Either way, we want to know the total area and the total volume. It might happen that the boxes completely enclose space that is not included in any of the boxes (see the second example below). Because the liquid cannot enter that space, its volume must be added to the total volume. Copper plate bordering this space is super?uous, of course, so it does not add to the area.

 

技术分享图片 Input

On the rst line one positive number: the number of testcases, at most 100. After that per testcase:

? One line with an integer n (1 ≤ n ≤ 50): the number of boxes involved.

? n lines with six positive integers x0,y0,z0,x ,y,z (1 ≤ x0,y0,z0,x,y,z ≤ 500): the triple (x0,y0,z0) is the vertex of the box with the minimum values for the coordinates and the numbers x, y, z are the dimensions of the box (x, y and z dimension, respectively). All dimensions are in centimeters. The sides of the boxes are always parallel to the coordinate axes.

 

技术分享图片 Output

Per testcase: ? One line with two numbers separated by single spaces: the total amount of copper plate needed (in cm2), and the total volume (in cm3).

 

技术分享图片 Sample Input

2
2
1 2 3 3 4 5
6 2 3 3 4 5
7
1 1 1 5 5 1
1 1 10 5 5 1
1 1 2 1 4 8
2 1 2 4 1 8
5 2 2 1 4 8
1 5 2 4 1 8
3 3 4 1 1 1

 

技术分享图片 Sample Output

188 120

250 250

 

题解:这个题还是挺费劲的,floodfill倒不是重点,困难的地方在于离散化(起码对我来说很困难),原来也做过两道离散化的题,但是对于这个东西没啥概念,这道题让我对离散化的理解深刻了一些。

离散化之后这里的长方体就变成了正方体,想到这一点对于理解整个思路很有帮助。

这里面还有一个思想就是用点代表长方体,此处用的是三个坐标均为最小的点来代表一个长方体。

lrj的代码中把函数封装在结构体感觉灰常方便,学习了。

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <queue>
  6 #include <algorithm>
  7 using namespace std;
  8 
  9 const int maxn = 50+5;
 10 const int maxl = 1000+1;
 11 
 12 int xl[maxn],yl[maxn],zl[maxn];
 13 int xr[maxn],yr[maxn],zr[maxn];
 14 
 15 int gra[maxn<<1][maxn<<1][maxn<<1];
 16 int xx[maxn<<1],yy[maxn<<1],zz[maxn<<1];
 17 int xcnt,ycnt,zcnt;
 18 
 19 int dx[6] = {1,-1,0,0,0,0};
 20 int dy[6] = {0,0,1,-1,0,0};
 21 int dz[6] = {0,0,0,0,1,-1};
 22 
 23 struct Point{
 24     int x,y,z;
 25     Point(int x = 0,int y = 0,int z = 0) :
 26         x(x),y(y),z(z) {}
 27     bool valid()const{
 28         if(0<=x && 0<=y && 0<=z && x<xcnt-1 && y<ycnt-1 && z<zcnt-1) return true;
 29         else return false;
 30     }
 31     bool solid()const{
 32         return gra[x][y][z] == 1;
 33     }
 34     void Setvis()const{
 35         gra[x][y][z] = 2;
 36     }
 37     bool Getvis()const{
 38         return gra[x][y][z] ==2;
 39     }
 40     Point neighbour(int i)const{
 41         return Point(x+dx[i],y+dy[i],z+dz[i]);
 42     }
 43     int volume()const{
 44         return (xx[x+1]-xx[x])*(yy[y+1]-yy[y])*(zz[z+1]-zz[z]);
 45     }
 46     int area(int dir)const{
 47         if(dx[dir] != 0) return (yy[y+1]-yy[y])*(zz[z+1]-zz[z]);
 48         else if(dy[dir] != 0) return (xx[x+1]-xx[x])*(zz[z+1]-zz[z]);
 49         else return (xx[x+1]-xx[x])*(yy[y+1]-yy[y]);
 50     }
 51 };
 52 
 53 int ID_find(int *num,int len,int tar){
 54     return lower_bound(num,num+len,tar)-num;
 55 }
 56 
 57 void floodfill(int &V,int &S){
 58     Point c;
 59     c.Setvis();
 60     queue<Point> que;
 61     que.push(c);
 62     while(!que.empty()){
 63         Point first = que.front();
 64         que.pop();
 65         V += first.volume();
 66         for(int i = 0;i < 6;i++){
 67             Point Next = first.neighbour(i);
 68             if(Next.valid()){
 69                 if(Next.solid()){
 70                     S += first.area(i);
 71                 }
 72                 else if(!Next.Getvis()){
 73                     Next.Setvis();
 74                     que.push(Next);
 75                 }
 76             }
 77         }
 78     }
 79     V = maxl*maxl*maxl-V;
 80 }
 81 
 82 void Unique(int *num,int cnt,int &ccnt){
 83     sort(num,num+cnt);
 84     ccnt = unique(num,num+cnt)-num;
 85 }
 86 
 87 int main()
 88 {
 89     //freopen("input.txt","r",stdin);
 90     int iCase;
 91     scanf("%d",&iCase);
 92     while(iCase--){
 93         int n;
 94         scanf("%d",&n);
 95         int cnt = 2;
 96         xx[0] = yy[0] = zz[0] = 0;
 97         xx[1] = yy[1] = zz[1] = maxl;
 98         for(int i = 0;i < n;i++){
 99             scanf("%d%d%d%d%d%d",&xl[i],&yl[i],&zl[i],&xr[i],&yr[i],&zr[i]);
100             xr[i] += xl[i],yr[i] += yl[i],zr[i] += zl[i];
101             xx[cnt] = xl[i],yy[cnt] = yl[i],zz[cnt++] = zl[i];
102             xx[cnt] = xr[i],yy[cnt] = yr[i],zz[cnt++] = zr[i];
103         }
104         Unique(xx,cnt,xcnt);
105         Unique(yy,cnt,ycnt);
106         Unique(zz,cnt,zcnt);
107         memset(gra,0,sizeof(gra));
108         for(int i = 0;i < n;i++){
109             int X1 = ID_find(xx,xcnt,xl[i]),X2 = ID_find(xx,xcnt,xr[i]);
110             int Y1 = ID_find(yy,ycnt,yl[i]),Y2 = ID_find(yy,ycnt,yr[i]);
111             int Z1 = ID_find(zz,zcnt,zl[i]),Z2 = ID_find(zz,zcnt,zr[i]);
112             for(int X = X1;X < X2;X++){            //这里一定是 < ,因为是以点代体,如果点到了边界,体就出去了
113                 for(int Y = Y1;Y < Y2;Y++){
114                     for(int Z = Z1;Z < Z2;Z++){
115                         gra[X][Y][Z] = 1;
116                     }
117                 }
118             }
119         }
120         int V = 0,S = 0;
121         floodfill(V,S);
122         printf("%d %d
",S,V);
123     }
124     return 0;
125 }

 

 












以上是关于UVA12171-Sculpture(离散化+floodfill)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 2771(uva 12171) Sculpture bfs+离散化

UVA 221 - Urban Elevations(离散化)!!!!!!

UVa Sculpture(离散化 floodfill)

uva12171 离散化

UVa 221城市正视图(离散化)

Unique Snowflakes UVA - 11572 (离散化+尺取法)