HDU3642 Get The Treasury —— 求矩形交体积 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/HDU-3642
Jack can’t get the total volume of the treasury because these regions don’t always contain treasury. Through years of experience, he discovers that if a region is detected that may have treasury at more than two different spots, the region really exist treasure. And now Jack only wants to know the minimum volume of the treasury.
Now Jack entrusts the problem to you.
InputThe first line of the input file contains a single integer t, the number of test cases, followed by the input data for each test case.
Each test case is given in some lines. In the first line there is an integer n (1 ≤ n ≤ 1000), the number of spots on the surface of the earth that he had detected. Then n lines follow, every line contains six integers x 1, y 1, z 1, x 2, y 2 and z2, separated by a space. The absolute value of x and y coordinates of the vertices is no more than 10 6, and that of z coordinate is no more than 500.
OutputFor each test case, you should output “Case a: b” in a single line. a is the case number, and b is the minimum volume of treasury. The case number is counted from one.
Sample Input
2
1
0 0 0 5 6 4
3
0 0 0 5 5 5
3 3 3 9 10 11
3 3 3 13 20 45
Sample Output
Case 1: 0
Case 2: 8
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 1e3+; int times[MAXN<<]; //times为该区间被覆盖的次数
int one[MAXN<<], two[MAXN<<], more[MAXN<<];
int Z[MAXN<<], X[MAXN<<]; //Z、X分别用于离散化Z坐标和X坐标 struct Cube
{
int x1, y1, z1,x2, y2, z2;
}cube[MAXN]; struct Line
{
int le, ri, h, id;
bool operator<(const Line &a)const{
return h<a.h;
} }line[MAXN<<]; void push_up(int u, int l, int r)
{
if(times[u]>=) //该区间被覆盖三次
{
more[u] = X[r] - X[l];
two[u] = X[r] - X[l];
one[u] = X[r] - X[l];
}
else if(times[u]==) //两次
{
more[u] = (l+==r)?:(one[u*]+one[u*+]);
two[u] = X[r] - X[l];
one[u] = X[r] - X[l];
}
else if(times[u]==) //一次
{
more[u] = (l+==r)?:(two[u*]+two[u*+]);
two[u] = (l+==r)?:(one[u*]+one[u*+]);
one[u] = X[r] - X[l];
}
else //没有被覆盖
{
more[u] = (l+==r)?:(more[u*]+more[u*+]);
two[u] = (l+==r)?:(two[u*]+two[u*+]);
one[u] = (l+==r)?:(one[u*]+one[u*+]);
}
} //此种线段树的操作对象为连续型,即最小的元素为长度为1的区间[l,r],其中l和r只代表端点(r-l>=1),用于确定
//区间的位置和长度,l和r本身没有特别的含义。而以往做的什么单点更新之类的,都属于离散型,在l处和r处是有含义的
void add(int u, int l, int r, int x, int y, int v)
{
if(x<=l && r<=y)
{
times[u] += v;
push_up(u, l, r);
return;
} int mid = (l+r)>>;
if(x<=mid-) add(u*, l, mid, x, y, v);
if(y>=mid+) add(u*+, mid, r, x, y, v);
push_up(u, l, r);
} int main()
{
int T, n;
scanf("%d", &T);
for(int kase = ; kase<=T; kase++)
{
scanf("%d", &n);
int numZ = ;
for(int i = ; i<=n; i++)
{
scanf("%d%d%d", &cube[i].x1,&cube[i].y1,&cube[i].z1);
scanf("%d%d%d", &cube[i].x2,&cube[i].y2,&cube[i].z2);
Z[++numZ] = cube[i].z1; Z[++numZ] = cube[i].z2;
} sort(Z+, Z++numZ); //离散化Z坐标
numZ = unique(Z+, Z++numZ) - (Z+); LL volume = ;
for(int i = ; i<numZ; i++) //枚举每一个平面(平面垂直于Z轴)
{
int numLine = , numX = ;
for(int j = ; j<=n; j++)
if(cube[j].z1<=Z[i] && Z[i+]<=cube[j].z2) //获得在此平面有效的长方体,然后保存他们在此平面的上下边。
{
line[++numLine].le = cube[j].x1; line[numLine].ri = cube[j].x2;
line[numLine].h = cube[j].y1; line[numLine].id = ;
line[++numLine].le = cube[j].x1; line[numLine].ri = cube[j].x2;
line[numLine].h = cube[j].y2; line[numLine].id = -;
X[++numX] = cube[j].x1; X[++numX] = cube[j].x2;
} sort(line+, line++numLine); //在此平面中,根据高度(即y坐标)对线段进行排序
sort(X+, X++numX);
numX = unique(X+, X++numX) - (X+); //离散化X坐标 memset(times, , sizeof(times));
memset(more, , sizeof(more));
memset(two, , sizeof(two));
memset(one, , sizeof(one)); LL area = ;
for(int j = ; j<numLine; j++) //计算此平面的有效面积
{
int l = upper_bound(X+, X++numX, line[j].le) - (X+);
int r = upper_bound(X+, X++numX, line[j].ri) - (X+);
add(, , numX, l, r, line[j].id);
area += 1LL*more[]*(line[j+].h-line[j].h);
}
volume += 1LL*area*(Z[i+]-Z[i]); //计算两个平面之间的体积,然后再累加
}
printf("Case %d: %lld\n", kase, volume);
}
}
HDU3642 Get The Treasury —— 求矩形交体积 线段树 + 扫描线 + 离散化的更多相关文章
- HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/HDU-1255 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<= ...
- HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
- POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)
题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...
- hdu 4419 线段树 扫描线 离散化 矩形面积
//离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...
- POJ1177 Picture —— 求矩形并的周长 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/POJ-1177 A number of rectangular posters, photographs and other pict ...
- poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)
题目链接 题意:给出n个矩形,每个矩形给左下 和 右上的坐标,求围成的周长的长度. 分析: 首先感谢大神的博客,最近做题经常看大神的博客:http://www.cnblogs.com/kuangbin ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积
#include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...
随机推荐
- LeetCode刷题笔记-递归-路径总和
题目描述: 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和. 说明: 叶子节点是指没有子节点的节点. 示例: 给定如下二叉树,以及目标和 su ...
- GitLab 安装和配置
一.GitLab 简介 GitLab 是一个利用Ruby on Rails 开发的开源版本控制系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目. 它拥有与GitHub类 ...
- 完善的IaaS云服务的个人理解
此文已由作者王盼授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 前情提要 本文仅讨论云主机(虚拟机).云硬盘(块存储).云网络(普通虚拟网络或SDN)相关的IaaS服务,相关 ...
- httpclient调用webservice接口的方法实例
这几天在写webservice接口,其他的调用方式要生成客户端代码,比较麻烦,不够灵活,今天学习了一下httpclient调用ws的方式,感觉很实用,话不多说,上代码 http://testhcm.y ...
- python和shell获取命令行参数的区别
一.命令行参数的取得对于一些功能性的脚本来说非常有用,不至于将功能写死在脚本中. shell的命令行参数直接用 $ 1,$2 等就可以直接获取 其中 $1 表示 第二个参数,即命令行的第一个参数,因为 ...
- 79. could not initialize proxy - no Session 【从零开始学Spring Boot】
[原创文章,转载请注明出处] Spring与JPA结合时,如何解决懒加载no session or session was closed!!! 实际上Spring Boot是默认是打开支持sessio ...
- 70.打印所有Spring boot载入的bean【从零开始学Spring Boot】
[从零开始学习Spirng Boot-常见异常汇总] 问题的提出: 我们在开发过程当中,我们可能会碰到这样的问题:No qualifying bean 就是我们定义的bean无法进行注入,那到底是什 ...
- POJ-Crazy tea party,很好的一道数学题~~~
Crazy tea party Time Limit: 1000MS Memory Limit: 10000K Description n participants of <& ...
- [bzoj1787][Ahoi2008]Meet 紧急集合(lca)
传送门 可以看出,三个点两两之间的lca会有一对相同,而另一个lca就是聚集点. 然后搞搞就可以求出距离了. ——代码 #include <cstdio> #include <cst ...
- ascii 和 byte以及UTF-8的转码规则
多年来闲麻烦,只记录笔记,不曾编写BLOG,本文为原创,如需转载请标明出处 废话不说,直奔主题 ascii 计算机只接受 “高”.“低”电压,所以使用二进制 1 和 0 分别代表高低电压 ...