题意:

给定n个立方体的一个顶点坐标和3边长度,  问这些立方体组成的雕塑的表面积和体积,   坐标都是整数,n最大为50,  最大为500, 边长最大也是500。

分析:

继UVa221后又一道离散化

首先先深入理解一下离散化: (转自 http://www.cnblogs.com/jerryRey/p/4599388.html)

先来看一个问题:给你以下的网格,你需要多少空间去存储红点区间的信息呢?

只需要图上所示的1,2,3,4个点就足够表示红点所在区间了,为什么不是一个区间的第一个红点和最后一个红点呢?(如果这样记录的话则必须加一区间点,记录区间内部信息,因为端点可能是两个区间的交集而区间内可能只被操作了一次)这样做的好处是空白区域的长度也能轻易计算出来。

因此离散化的核心在于以点代表区间

对于本题, 如果直接建一个1000*1000*1000的数组进行floodfill , 方法是可行的, 但是从数据上看可能会爆内存+超时, 因为这里数据规模已经到了1e9.

所以我们需要离散化出我们要用的坐标, 对于50个立方体来说, 我们每一个维度(xyz)最大会有50*2 = 100个不同的坐标, 那么我们就可以把这些坐标的区间段记录下来, 这些区间段的性质都是一样的(要么没有东西, 要么是立方体), 所以我们就可以把一个区间离散化为一个点, 然后将这些点填入一个100*100*100的数组做floodfill (数据规模1e6)。

因为本题还有有很多细节的地方, 所以我没有独立编程去实现, 贴一个对刘汝佳代码注释过的代码。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = + ;
const int maxc = + ; //原来的数据
int n, x0[maxn], x1[maxn], y0[maxn], y1[maxn], z0[maxn], z1[maxn]; //离散化 (将每个线段离散为一个点)
int nx, ny, nz;
int xs[maxn*], ys[maxn*], zs[maxn*]; //六个方向 如果是xz面看的话 就是 右左前后上下
const int dx[] = {,-,,,,};
const int dy[] = {,,,-,,};
const int dz[] = {,,,,,-}; //离散化数组,每一个点都是代表原来的一个线段(不一定是原来的矩形, 可能是矩形的一部分), 在这个坐标内floodfill
int color[maxn*][maxn*][maxn*]; //
struct cube{
int x, y, z; //只要有xyz这个点 , 就能在color数组内对应空气或者实体
cube(int x = , int y = , int z = ): x(x) , y(y) , z(z){}
bool valid() const{
//每个点的左闭右开区间代表一个线段, 而且最后一个点就是范围极限(它不代表一个线段), 所以范围应该是[0, 最后一个点的前一个]
//下标从0开始 一直到 nx - 1 个点
return x >= && x < nx - && y >= && y < ny- && z>= && z < nz -;
} bool solid() const{
//判断这个点代表的是空气还是实体
return color[x][y][z] == ;
} bool getvis() const{
//判断是否被访问过
return color[x][y][z] == ;
} void setvis() const{
color[x][y][z] = ;
}
//访问他的邻居 访问要先判断是否 valid
cube neighbor(int dir) const{
return cube(x+dx[dir], y+dy[dir], z+dz[dir]);
}
int volume() const{
//要计算这个color点的体积, 要重新找回这个color点原始的数据
return (xs[x+] - xs[x]) * (ys[y+] -ys[y]) * (zs[z+]-zs[z]);
}
int area(int dir) const{//计算表面积
//想象一下 如果遍历过程中向上碰到solid, 那么说明这肯定是一个 xy型的面, 所以可以加上x*y
if(dx[dir] != ) return (ys[y+] - ys[y]) * (zs[z+]-zs[z]);
else if(dy[dir] != ) return (xs[x+] - xs[x]) * (zs[z+] - zs[z]);
return (xs[x+] - xs[x]) * (ys[y+] - ys[y]);
}
}; void discretize(int* x, int& n){
sort(x,x+n); //默认升序
n = unique(x,x+n) - x; // 这样就可以求出有多少个不同的元素
}
int ID(int* x, int n, int x0){//使原来矩形的数据对应离散化数组的下标
return lower_bound(x, x+n, x0) - x; //返回一个等于x0的下标
} void floodfill(int&v , int& s){
v = ;
s = ;
cube c;
c.setvis();
queue<cube> q;//碰到空气就入队, 碰到solid计算表面积
q.push(c);
while(!q.empty()){
cube c = q.front(); q.pop();
v += c.volume(); //出队空气的体积
for(int i = ; i < ; i++){
cube c2 = c.neighbor(i);
if(!c2.valid()) continue;
if(c2.solid()) s += c.area(i);
else if(!c2.getvis()){
c2.setvis();
q.push(c2);
}
}
}
v = maxc*maxc*maxc - v;
} int main(){
int T;
scanf("%d", &T);
while(T--){
nx = ny = nz = ;
xs[] = ys[] = zs[] = ;//给定下界 让空气可以严格包围矩形
xs[] = ys[] = zs[] = maxc; // 同上 scanf("%d", &n);
for(int i = ; i < n ;i++){
scanf("%d %d %d %d %d %d", &x0[i], &y0[i], &z0[i], &x1[i], &y1[i], &z1[i]);
x1[i] += x0[i], y1[i] += y0[i], z1[i] += z0[i]; xs[nx++] = x0[i], xs[nx++] = x1[i];
ys[ny++] = y0[i], ys[ny++] = y1[i];
zs[nz++] = z0[i], zs[nz++] = z1[i];
}
discretize(xs,nx);//离散化, 传入一个数组坐标和一个应用变量, 去重输出有多少段
discretize(ys,ny);
discretize(zs,nz);
memset(color, , sizeof(color));//初始化color 准备用坐标填入
for(int i = ; i < n; i++){
int X1 = ID(xs,nx,x0[i]), X2 = ID(xs,nx,x1[i]);
int Y1 = ID(ys,ny,y0[i]), Y2 = ID(ys,ny,y1[i]);
int Z1 = ID(zs,nz,z0[i]), Z2 = ID(zs,nz,z1[i]);
//左开右闭区间代表线段
for(int X = X1; X < X2; X++){
for(int Y = Y1; Y < Y2; Y++){
for(int Z = Z1; Z < Z2; Z++){
color[X][Y][Z] = ;
}
}
}
}
int v, s;
floodfill(v, s);
printf("%d %d\n",s,v);
}
}

UVa Sculpture(离散化 floodfill)的更多相关文章

  1. Uva 12171 Sculpture - 离散化 + floodfill

    题目连接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  2. UVa 12171 (离散化 floodfill) Sculpture

    题意: 三维空间中有n个长方体组成的雕塑,求表面积和体积. 分析: 我们可以在最外边加一圈“空气”,然后求空气的连通块的体积,最后用总体积减去即是雕塑的体积. 还有一个很“严重”的问题就是5003所占 ...

  3. UVA12171-Sculpture(离散化+floodfill)

    Problem UVA12171-Sculpture Accept: 196  Submit: 1152 Time Limit: 3000 mSec Problem Description Imagi ...

  4. 【紫书】Urban Elevations UVA - 221 离散化

    题意:给你俯视图,要求依次输出正视图中可以看到的建筑物 题解:任意相邻的x间属性相同,所以离散化. 坑:unique只能对数组用.下标易错 list不能找某元素的next.用了个很麻烦的处理 数组: ...

  5. UVA 572 Oil Deposits油田(DFS求连通块)

    UVA 572     DFS(floodfill)  用DFS求连通块 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format: ...

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

    题意: 给出一些边平行于坐标轴的长方体,这些长方体可能相交.也可能相互嵌套.这些长方体形成了一个雕塑,求这个雕塑的整体积和表面积. 题解: 最easy想到直接进行bfs或者dfs统计,但此题的麻烦之处 ...

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

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  8. UVa 1471 Defense Lines - 线段树 - 离散化

    题意是说给一个序列,删掉其中一段连续的子序列(貌似可以为空),使得新的序列中最长的连续递增子序列最长. 网上似乎最多的做法是二分查找优化,然而不会,只会值域线段树和离散化... 先预处理出所有的点所能 ...

  9. UVa 221 Urban Elevations 城市正视图 离散化初步 无限化有限

    转载请注明: 仰望高端玩家的小清新 http://www.cnblogs.com/luruiyuan/ 题目大意: 题目传送门:UVa 221 Urban Elevations 给出城市中建筑物的x, ...

随机推荐

  1. 【SpringCloud构建微服务系列】微服务网关Zuul

    一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...

  2. 《Windows核心编程系列》十二谈谈Windows内存体系结构

    Windows内存体系结构 理解Windows内存体系结构是每一个励志成为优秀的Windows程序员所必须的. 进程虚拟地址空间 每个进程都有自己的虚拟地址空间.对于32位操作系统来说,它的地址空间是 ...

  3. 51nod 1088 最长回文子串

    1088 最长回文子串 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串. 输入一 ...

  4. git介绍及安装

    git介绍 git是一个开源的分布式版本控制系统,用于敏捷高效的处理任何或大或小的项目.git是linus Torvalds为了帮助管理Linux内核开发的一个开放源码的版本控制软件. Git 与常用 ...

  5. asp.net core连接sqlserver

    开发环境:win7,vs2017,sqlserver2014 vs上建立一个asp.net core web项目和一个.net core的类库项目DBA 简单起见,在DBA项目中就一个类SqlServ ...

  6. MFC显示文本文档 分类: MFC 2014-12-30 10:03 457人阅读 评论(1) 收藏

    新建基于对话框的MFC应用程序.资源视图的对话框上添加编辑框(Edit Control)和按钮(Button), 将编辑框属性:Mutiline.Auto HScroll.Auto VScroll设为 ...

  7. jmeter(二)元件的作用域与执行顺序

    1.元件的作用域 JMeter中共有8类可被执行的元件(测试计划与线程组不属于元件),这些元件中,取样器是典型的不与其它元件发生交互作用的元件,逻辑控制器只对其子节点的取样器有效,而其它元件(conf ...

  8. Lucky Number Eight dp

    https://www.hackerrank.com/contests/w28/challenges/lucky-number-eight 设dp[i][v]表示前i位数中,得到余数是v的子序列的数目 ...

  9. D. Arpa's weak amphitheater and Mehrdad's valuable Hoses 分组背包模板题

    http://codeforces.com/problemset/problem/742/D 并查集预处理出所有关系. 一开始的时候,我预处理所有关系后,然后选择全部的时候,另起了一个for,然后再判 ...

  10. commons-lang常用工具类StringEscapeUtils使用--转

    https://my.oschina.net/ydsakyclguozi/blog/341496 在apache commons-lang(2.3以上版本)中为我们提供了一个方便做转义的工具类,主要是 ...