题意:

给出一些边平行于坐标轴的长方体,这些长方体可能相交。也可能相互嵌套。这些长方体形成了一个雕塑,求这个雕塑的整体积和表面积。

题解:

最easy想到直接进行bfs或者dfs统计,但此题的麻烦之处在于求整个雕塑的外表面积和雕塑内部可能出现四个长方体所搭成的空心。空心不能计算到表面积中,可是计算整体积却要计入,于是直接bfs或者dfs不优点理。于是,能够想到直接统计整个雕塑外围的全部小方块。就可以非常方便地求出雕塑地表面积和体积(雕塑地整体积==整个空间地体积-外围想方块的体积),另一点就是因为坐标范围达到1-1000,
整个空间的大小达到了1000*1000*1000 = 1e9, 直接bfs明显会超时,因为长方体的个数最大仅仅有50个,于是能够对原坐标进行离散化,把每一维的坐标离散化后,整个空间的大小缩小到了100*100*100 = 1e6,于是这个问题就攻克了。

(具体參考代码。凝视地非常具体)。

代码:(參考了标程。非常美丽地代码)

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 50 + 5;
const int maxc = 1000 + 1; int n;
int x0[maxn], y0[maxn], z0[maxn], x1[maxn], y1[maxn], z1[maxn];
int xs[maxn*2], ys[maxn*2], zs[maxn*2], nx, ny, nz;
int color[maxn*2][maxn*2][maxn*2];
int dx[] = {0, 0, 0, 0, -1, 1};
int dy[] = {0, 0, -1, 1, 0, 0};
int dz[] = {-1, 1, 0, 0, 0, 0}; struct Cell
{
int x, y, z;
Cell(int x = 0, int y = 0, int z = 0) : x(x), y(y), z(z) {}
void setVis() const {
color[x][y][z] = 2;
}
int volume() const {
return (xs[x+1]-xs[x])*(ys[y+1]-ys[y])*(zs[z+1]-zs[z]);
}
Cell neighbor(int i) const {
return Cell(x+dx[i], y+dy[i], z+dz[i]);
}
bool valid() const {
return x>=0 && x<nx-1 && y>=0 && y<ny-1 && z>=0 && z<nz-1;
}
bool solid() const {
return color[x][y][z] == 1;
}
int area(int i) const {
if (dx[i] != 0) return (ys[y+1]-ys[y])*(zs[z+1]-zs[z]);
else if(dy[i] != 0) return (xs[x+1]-xs[x])*(zs[z+1]-zs[z]);
else return (xs[x+1]-xs[x])*(ys[y+1]-ys[y]);
}
bool getVis() const {
return color[x][y][z] == 2;
}
}; void discretize(int* x, int& n) //对每一维进行离散化
{
sort(x, x + n);
n = (int)(unique(x, x+n) - x);
}
int ID(int* x, int n, int x0) //找到原坐标离散化后的新坐标
{
return (int)(lower_bound(x, x+n, x0) - x);
}
void floodfill(int& s, int& v) //bfs 统计
{
s = v = 0;
Cell c; c.setVis();
queue<Cell> Q; Q.push(c); while (!Q.empty())
{
Cell now = Q.front(); Q.pop();
v += now.volume(); //统计雕塑外围的整体积
for (int i = 0; i < 6; i++)
{
Cell nxt = now.neighbor(i);
if (!nxt.valid()) continue; //越界
if (nxt.solid()) s += now.area(i); //统计雕塑外围表面积
else if(!nxt.getVis())
{
nxt.setVis();
Q.push(nxt);
}
}
}
v = maxc*maxc*maxc - v; //雕塑体积 == 整个空间的体积-雕塑外围体积
}
int main()
{
// freopen("/Users/apple/Desktop/in.txt", "r", stdin); int t; scanf("%d", &t); while (t--)
{
scanf("%d", &n);
nx = ny = nz = 2;
xs[0] = ys[0] = zs[0] = 0;
xs[1] = ys[1] = zs[1] = maxc; //存入边界坐标
for (int i = 0; i < n; i++)
{
scanf("%d%d%d", &x0[i], &y0[i], &z0[i]);
scanf("%d%d%d", &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, 0, sizeof(color)); //染色
for (int i = 0; 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] = 1;
}
}
}
}
int s, v;
floodfill(s, v);
printf("%d %d\n", s, v);
} return 0;
}

hdu 2771(uva 12171) Sculpture bfs+离散化的更多相关文章

  1. Uva 12171 Sculpture - 离散化 + floodfill

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

  2. UVA 12171 Sculpture

    https://vjudge.net/problem/UVA-12171 题目 某人设计雕塑,用的是很扯的方法:把一堆长方体拼起来.给出长方体的坐标和长宽高,求外表面积.因为要将这雕塑进行酸洗,需要知 ...

  3. HDU 2717 Catch That Cow --- BFS

    HDU 2717 题目大意:在x坐标上,农夫在n,牛在k.农夫每次可以移动到n-1, n+1, n*2的点.求最少到达k的步数. 思路:从起点开始,分别按x-1,x+1,2*x三个方向进行BFS,最先 ...

  4. UVA 12171 (hdu 2771)sculptrue(离散化)

    以前对离散化的理解不够,所以把端点和区间区分来考虑但是做完这题以后有了新的认识: 先来看一个问题:给你以下的网格,你需要多少空间去存储红点区间的信息呢? 只需要图上所示的1,2,3,4个点就足够表示红 ...

  5. uva 12171 hdu 1771 Sculpture

    //这题从十一点开始写了四十分钟 然后查错一小时+ 要吐了 这题题意是给很多矩形的左下角(x,y,z最小的那个角)和三边的长(不是x,y,z最大的那个角T-T),为组成图形的面积与表面积(包在内部的之 ...

  6. UVa 12171 (离散化 floodfill) Sculpture

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

  7. HDU 5876 关于补图的bfs

    1.HDU 5876  Sparse Graph 2.总结:好题,把STL都过了一遍 题意:n个点组成的完全图,删去m条边,求点s到其余n-1个点的最短距离. 思路:把点分为两个集合,A为所有没有到达 ...

  8. hdu 1240:Asteroids!(三维BFS搜索)

    Asteroids! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  9. HDU(1175),连连看,BFS

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1175 越学越不会,BFS还是很高级的. 连连看 Time Limit: 20000/100 ...

随机推荐

  1. iOS开发之二维码扫描

    二维码扫描 01-导入系统库 02 新建继承自UIView的 LHQPreView 2.1导入系统库头文件 #import <AVFoundation/AVFoundation.h> 2. ...

  2. Eclipse Alt+/ 智能提示失效

    Eclipse3.7  自动提示Alt+/不能导入包,且General->Keys->content assist中已经检查并无快捷键冲突 Eclipse中window->Prefe ...

  3. 序列化ADODataSet, ADOQuery

    经过昨天晚上一折腾把做了一个DIOCP直接传递TADOQuery的Demo,在google上找了一系列的资料. 这样服务端可以直接将TADOQuery查询出来的数据直接转换成TStream自己进行传递 ...

  4. LeetCode: Validate Binary Search Tree 解题报告

    Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST) ...

  5. Python3机器学习—Tensorflow数字识别实践

    [本文出自天外归云的博客园] Windows下Anaconda+Tensorflow环境部署 1. 安装Anaconda. 2. 开始菜单 > 所有程序 > Anaconda 3 (64- ...

  6. 第一个驱动之字符设备驱动(二)mdev

    mdev是busybox提供的一个工具,用在嵌入式系统中,相当于简化版的udev,作用是在系统启动和热插拔或动态加载驱动程序时, 自动创建设备节点.文件系统中的/dev目录下的设备节点都是由mdev创 ...

  7. JAVA-数据库之查询记录

    相关资料:<21天学通Java Web开发> ResultSet结果集1.使用exectteQuery()方法查询数据.2.exectueQuery()方法接收一个查询SQL语句.3.返回 ...

  8. mac电脑的系统偏好设置的安全与隐私的任何来源没有了

    打开电脑搜索   输入终端   打开终端输入 sudo spctl --master-disable

  9. java框架篇---struts之OGNL详解

    OGNL(Object Graph Navigation Language),是一种表达式语言.使用这种表达式语言,你可以通过某种表达式语法,存取Java对象树中的任意属性.调用Java对象树的方法. ...

  10. 调整Intellij IDEA内存

    最近IDEA真是卡的要死,下面