UVA 12171 (hdu 2771)sculptrue(离散化)
以前对离散化的理解不够,所以把端点和区间区分来考虑但是做完这题以后有了新的认识:
先来看一个问题:给你以下的网格,你需要多少空间去存储红点区间的信息呢?

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

为了计算总区间两端空白的长度,增加A和B点。
原数据找离散后的值直接二分,没必要建map,因为map的查询也是logN级别的
知道了这些,存储问题就解决了。
/*
Created by Rey Chen on 2015.6.25
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
//#define local
using namespace std;
const int maxn = + ;
const int max2n = + ;
const int maxc = + ;//coordinate;
typedef int ll;
// original data
int n, x0[maxn], y0[maxn], z0[maxn], x1[maxn], y1[maxn], z1[maxn];
// discretized data
int xs[max2n], ys[max2n], zs[max2n];
int xn, yn, zn;//the numbers of each coordinate //1 means solid, 2 means visited air
int color[max2n][max2n][max2n]; void discretize(int* x, int& n) {
sort(x, x+n);
n = unique(x, x+n) - x;
} struct Cell
{
int x, y, z;
Cell(int x,int y,int z):x(x),y(y),z(z){}
};
//related to flood fill
const int dx[] = {,-,,,,};
const int dy[] = {,,,-,,};
const int dz[] = {,,,,,-}; #define vis(u) (color[v.x][v.y][v.z] == 2)
#define setVis(u) color[u.x][u.y][u.z] = 2//solid..
#define uNeigh(i) Cell v(u.x+dx[i], u.y+dy[i], u.z+dz[i])
#define inside(v) (v.x >=0 && v.x < xn && v.y >= 0 && v.y < yn && v.z >= 0 && v.z < zn)
#define issolid(v) (color[v.x][v.y][v.z] == 1)
#define dis(u,x) (x##s[u.x+1]-x##s[u.x])
#define vol(u) (ll)(xs[u.x+1]-xs[u.x])*(ys[u.y+1]-ys[u.y])*(zs[u.z+1]-zs[u.z])//为了让原本最后一层空气计算时不下标不越界 还要再加一层 inline ll area(Cell& v, int dir){
if(dx[dir]) return (ll)dis(v,y)*dis(v,z);
if(dy[dir]) return (ll)dis(v,x)*dis(v,z);
return (ll)dis(v,x)*dis(v,y);
} //dfs might stack overflow
void floodfill(ll &V,ll &s)
{
queue<Cell> q;
Cell u(,,);// Cell u = Cell() 1,2
setVis(u);
q.push(u);
V = s = ;
while(!q.empty()) {
u = q.front();q.pop();
V += vol(u); //calculate air volume
for(int i = ; i < ; i++) {
uNeigh(i);
if(!inside(v)) continue;//最后一层不加
if(issolid(v)) s += area(v,i); //ensure air vis once meet solid add area
else if(!vis(v)) {
setVis(v);
q.push(v);
}
}
}
V = maxc*maxc*maxc - V;
} #define add(x) x##1[i] += x##0[i]
#define dadd(a) xs[t] = x##a[i]; ys[t] = y##a[i]; zs[t++] = z##a[i]
#define ID(x,n,val) (lower_bound(x,x+n,val) - x)
#define GetId(X,x) X##0 = ID(x##s, x##n, x##0[i]);X##1 = ID(x##s, x##n, x##1[i])
//X0 = ID(xs,xn,x0[i]);
int main()
{
#ifdef local
freopen("in.txt","r",stdin);
#endif // local int T;
scanf("%d",&T);
while(T--) {
scanf("%d",&n); int t = ;
*xs = *ys = *zs = ;//add air
xs[] = ys[] = zs[] = maxc;//最后面有两层空气
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);
add(x);add(y);add(z);
dadd(); dadd();
}
xn = yn = zn = t ;
discretize(xs,xn);
discretize(ys,yn);
discretize(zs,zn);
xn--;yn--;zn--;//不访问最后一层空气,计算总体积时要加上最后一层空气 memset(color,,sizeof(color));
for(int i = ; i < n; i++) { //solid set
int X0, X1, Y0, Y1, Z0, Z1;
GetId(X,x); GetId(Y,y); GetId(Z,z);
for(int X = X0; X < X1; X++)
for(int Y = Y0; Y < Y1; Y++)
for(int Z = Z0; Z < Z1; Z++)
color[X][Y][Z] = ;
}
ll v,s;
floodfill(v,s);
printf("%d %d\n",s,v);
}
return ;
}
UVA 12171 (hdu 2771)sculptrue(离散化)的更多相关文章
- uva 12171 hdu 1771 Sculpture
//这题从十一点开始写了四十分钟 然后查错一小时+ 要吐了 这题题意是给很多矩形的左下角(x,y,z最小的那个角)和三边的长(不是x,y,z最大的那个角T-T),为组成图形的面积与表面积(包在内部的之 ...
- hdu 2771(uva 12171) Sculpture bfs+离散化
题意: 给出一些边平行于坐标轴的长方体,这些长方体可能相交.也可能相互嵌套.这些长方体形成了一个雕塑,求这个雕塑的整体积和表面积. 题解: 最easy想到直接进行bfs或者dfs统计,但此题的麻烦之处 ...
- Uva 12171 Sculpture - 离散化 + floodfill
题目连接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- UVa 12171 (离散化 floodfill) Sculpture
题意: 三维空间中有n个长方体组成的雕塑,求表面积和体积. 分析: 我们可以在最外边加一圈“空气”,然后求空气的连通块的体积,最后用总体积减去即是雕塑的体积. 还有一个很“严重”的问题就是5003所占 ...
- UVa 221城市正视图(离散化)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVA 10816 + HDU 1839 Dijstra + 二分 (待研究)
UVA 题意:两个绿洲之间是沙漠,沙漠的温度不同,告诉起点,终点,求使得从起点到终点的最高温度最小的路径,如果有多条,输出长度最短的路径: 思路:用最小费用(最短路径)最大流(最小温度)也能搞吧,但因 ...
- HDU - 1255 扫描线+离散化进阶
这道题最开始我以为和HDU - 1542 那道题一样,只需要把cover次数改成2次即可,但是后面仔细一想,我们需要求的是覆盖次数大于等于2次的,这样的话,我们需要维护两个长度,HDU-1542 由于 ...
- HDU 5925 Coconuts 离散化
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5925 Coconuts Time Limit: 9000/4500 MS (Java/Others) ...
- hdu 5303 DP(离散化,环形)+贪心
题目无法正常粘贴,地址:http://acm.hdu.edu.cn/showproblem.php?pid=5303 大意是给出一个环形公路,和它的长度,给出若干颗果树的位置以及树上的果子个数. 起点 ...
随机推荐
- c/c++语言实现tesseract ocr引擎编程实例
编译下面的程序操作系统必须在安装了tesseract库和leptonica库才可以 Basic example c++ code: #include <tesseract/baseapi.h&g ...
- [poj百练]2754:八皇后 回溯
描述 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后 ...
- 浅谈Unity的渲染优化(1): 性能分析和瓶颈判断(上篇)
http://www.taidous.com/article-667-1.html 前言 首先,这个系列文章做个大致的介绍,题目"浅谈Unity",因为公司和国内大部分3D手游开发 ...
- Linux运用一些常用命令
今天搜集整理了一些Linux服务器运维常用命令,希望对大家有帮助:1.删除0字节文件 find -type f -size 0 -exec rm -rf {} 2.查看进程按内存从大到小排列 ps - ...
- js new Date("2016-07-01 08:00:00") 格式在IE内核浏览器中显示NaN的问题
js new Date("2016-07-01 08:00:00") 格式在IE内核浏览器中显示NaN的问题 废话就不多了,var dd = new Date("2016 ...
- docker网络设置(待整理)
手动指定容器的配置 -h HOSTNAME or --hostname=HOSTNAME \\设定容器的主机名. --dns=IP_ADDRESS \\指定DNS地址. ...
- jquery.jscrollpane.js滚动速度设置
首先找到插件里面的这个函数,改变成下面的样子: function initMousewheel() { container.unbind(mwEvent).bind( mwEvent, functio ...
- 题解 [HNOI2002]DNA分子的最佳比对 (洛谷P2268)
题目传送门 (这道题告诉我:初始化要小心) 有没有一点最长公共子序列的赶脚(口胡) 但我觉得挺像 设 表示匹配到s1的第i位,s2的第j位,则有 的初始化要注意:根据的含义,表示s1[i]一直在匹配空 ...
- 2017 Multi-University Training Contest - Team 7 Just do it
http://acm.hdu.edu.cn/showproblem.php?pid=6129 题意:一次操作就是i从1~n有 A[i]=A[i]^A[i-1]^A[i-2]...^A[1] 那么这样操 ...
- NET Core使用Quartz
NET Core使用Quartz 一.前言运用场景 Quartz.Net是一个强大.开源.轻量的作业调度框架,在平时的项目开发当中也会时不时的需要运用到定时调度方面的功能,例如每日凌晨需要统计前一天的 ...