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 superfluous, 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的代码中把函数封装在结构体感觉灰常方便,学习了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <algorithm>
using namespace std; const int maxn = +;
const int maxl = +; int xl[maxn],yl[maxn],zl[maxn];
int xr[maxn],yr[maxn],zr[maxn]; int gra[maxn<<][maxn<<][maxn<<];
int xx[maxn<<],yy[maxn<<],zz[maxn<<];
int xcnt,ycnt,zcnt; int dx[] = {,-,,,,};
int dy[] = {,,,-,,};
int dz[] = {,,,,,-}; struct Point{
int x,y,z;
Point(int x = ,int y = ,int z = ) :
x(x),y(y),z(z) {}
bool valid()const{
if(<=x && <=y && <=z && x<xcnt- && y<ycnt- && z<zcnt-) return true;
else return false;
}
bool solid()const{
return gra[x][y][z] == ;
}
void Setvis()const{
gra[x][y][z] = ;
}
bool Getvis()const{
return gra[x][y][z] ==;
}
Point neighbour(int i)const{
return Point(x+dx[i],y+dy[i],z+dz[i]);
}
int volume()const{
return (xx[x+]-xx[x])*(yy[y+]-yy[y])*(zz[z+]-zz[z]);
}
int area(int dir)const{
if(dx[dir] != ) return (yy[y+]-yy[y])*(zz[z+]-zz[z]);
else if(dy[dir] != ) return (xx[x+]-xx[x])*(zz[z+]-zz[z]);
else return (xx[x+]-xx[x])*(yy[y+]-yy[y]);
}
}; int ID_find(int *num,int len,int tar){
return lower_bound(num,num+len,tar)-num;
} void floodfill(int &V,int &S){
Point c;
c.Setvis();
queue<Point> que;
que.push(c);
while(!que.empty()){
Point first = que.front();
que.pop();
V += first.volume();
for(int i = ;i < ;i++){
Point Next = first.neighbour(i);
if(Next.valid()){
if(Next.solid()){
S += first.area(i);
}
else if(!Next.Getvis()){
Next.Setvis();
que.push(Next);
}
}
}
}
V = maxl*maxl*maxl-V;
} void Unique(int *num,int cnt,int &ccnt){
sort(num,num+cnt);
ccnt = unique(num,num+cnt)-num;
} int main()
{
//freopen("input.txt","r",stdin);
int iCase;
scanf("%d",&iCase);
while(iCase--){
int n;
scanf("%d",&n);
int cnt = ;
xx[] = yy[] = zz[] = ;
xx[] = yy[] = zz[] = maxl;
for(int i = ;i < n;i++){
scanf("%d%d%d%d%d%d",&xl[i],&yl[i],&zl[i],&xr[i],&yr[i],&zr[i]);
xr[i] += xl[i],yr[i] += yl[i],zr[i] += zl[i];
xx[cnt] = xl[i],yy[cnt] = yl[i],zz[cnt++] = zl[i];
xx[cnt] = xr[i],yy[cnt] = yr[i],zz[cnt++] = zr[i];
}
Unique(xx,cnt,xcnt);
Unique(yy,cnt,ycnt);
Unique(zz,cnt,zcnt);
memset(gra,,sizeof(gra));
for(int i = ;i < n;i++){
int X1 = ID_find(xx,xcnt,xl[i]),X2 = ID_find(xx,xcnt,xr[i]);
int Y1 = ID_find(yy,ycnt,yl[i]),Y2 = ID_find(yy,ycnt,yr[i]);
int Z1 = ID_find(zz,zcnt,zl[i]),Z2 = ID_find(zz,zcnt,zr[i]);
for(int X = X1;X < X2;X++){ //这里一定是 < ,因为是以点代体,如果点到了边界,体就出去了
for(int Y = Y1;Y < Y2;Y++){
for(int Z = Z1;Z < Z2;Z++){
gra[X][Y][Z] = ;
}
}
}
}
int V = ,S = ;
floodfill(V,S);
printf("%d %d\n",S,V);
}
return ;
}
UVA12171-Sculpture(离散化+floodfill)的更多相关文章
- Uva 12171 Sculpture - 离散化 + floodfill
题目连接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- UVa Sculpture(离散化 floodfill)
题意: 给定n个立方体的一个顶点坐标和3边长度, 问这些立方体组成的雕塑的表面积和体积, 坐标都是整数,n最大为50, 最大为500, 边长最大也是500. 分析: 继UVa221后又一道离散 ...
- UVa 12171 (离散化 floodfill) Sculpture
题意: 三维空间中有n个长方体组成的雕塑,求表面积和体积. 分析: 我们可以在最外边加一圈“空气”,然后求空气的连通块的体积,最后用总体积减去即是雕塑的体积. 还有一个很“严重”的问题就是5003所占 ...
- hdu 2771(uva 12171) Sculpture bfs+离散化
题意: 给出一些边平行于坐标轴的长方体,这些长方体可能相交.也可能相互嵌套.这些长方体形成了一个雕塑,求这个雕塑的整体积和表面积. 题解: 最easy想到直接进行bfs或者dfs统计,但此题的麻烦之处 ...
- UVa12171 hdu2771 UVaLive4291 Sculpture
填坑系列(p.171) orz rjl 代码基本和rjl的一样 #include<cstdio> #include<cstring> #include<cstdlib&g ...
- UVA 12171 Sculpture
https://vjudge.net/problem/UVA-12171 题目 某人设计雕塑,用的是很扯的方法:把一堆长方体拼起来.给出长方体的坐标和长宽高,求外表面积.因为要将这雕塑进行酸洗,需要知 ...
- UVA 12171 (hdu 2771)sculptrue(离散化)
以前对离散化的理解不够,所以把端点和区间区分来考虑但是做完这题以后有了新的认识: 先来看一个问题:给你以下的网格,你需要多少空间去存储红点区间的信息呢? 只需要图上所示的1,2,3,4个点就足够表示红 ...
- NBUT 1457 莫队算法 离散化
Sona Time Limit:5000MS Memory Limit:65535KB 64bit IO Format: Submit Status Practice NBUT 145 ...
- 项目安排(离散化+DP)
题目来源:网易有道2013年校园招聘面试二面试题 题目描述: 小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的 ...
随机推荐
- ServerSocket和Socket
前言 用ServerSocket和Socket做了个Server.Client通信的demo,以及学习下在这个demo过程中用到java.net.java.io包下几个常用的类. Server imp ...
- 【转载】Sqlserver的SQL语句实现分页查询
在应用程序的开发中,如果数据库中的数据量过于的庞大,则需要针对查询数据做分页处理,取出对应分页中的数据,在Sqlserver分页的语句写法中,有两种比较常用,一种是数据表中含有自增量Id的情况,可以根 ...
- 延迟初始化Lazy
延迟初始化出现于.NET 4.0,主要用于提高性能,避免浪费计算,并减少程序内存要求.也可以称为,按需加载. 基本语法: Lazy<T> xx = new Lazy<T>(); ...
- Linux中重命名乱码文件
Linux下,如何将一个乱码的文件进行重命名 方法一: 命令格式:mv $(ls |egrep "[^a-zA-Z0-9.-]") tandao.tx [root@nb o]# l ...
- JavaSE Lambda表达式(JDK1.8新特性)
在前面有一篇写到了Lambda表达式,现在可以给你们介绍什么是Lambda表达式 现在有很多老程序员都不喜欢这个函数式编程思想 主要就一点 : 老程序员习惯了 面向过程 写程序,而Lambda表达式是 ...
- 【Java基础】4、java中的内部类
内部类的分类:常规内部类.静态内部类.私有内部类.局部内部类.匿名内部类. 实例1:常规内部类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...
- PHP FastCGI进程管理器PHP-FPM的架构
一个master进程,支持多个pool,每个pool由master进程监听不同的端口,pool中有多个worker进程.每个worker进程都内置PHP解释器,并且进程常驻后台,支持prefork动态 ...
- Mybatis逆向工程生成po、mapper接口、mapper.xml
Mybatis逆向工程生成po.mapper接口.mapper.xml 一.新建一个maven工程 请查看我的另一篇博客:<使用idea创建一个maven工程> 二.引入所需依赖 需要my ...
- vue选中与取消简单实现
<li v-for="(item,index) in assign" :key="index" @click="selected(item)&q ...
- canvas-0trasform.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...