题目链接:https://vjudge.net/problem/HDU-3642

Jack knows that there is a great underground treasury in a secret region. And he has a special device that can be used to detect treasury under the surface of the earth. One day he got outside with the device to ascertain the treasury. He chose many different locations on the surface of the earth near the secret region. And at each spot he used the device to detect treasury and got some data from it representing a region, which may contain treasury below the surface. The data from the device at each spot is six integers x 1, y 1, z 1, x 2, y 2 and z 2 (x 1<x 2, y 1<y 2, z 1<z 2). According to the instruction of the device they represent the range of x, y and z coordinates of the region. That is to say, the x coordinate of the region, which may contain treasury, ranges from x 1 to x 2. So do y and z coordinates. The origin of the coordinates is a fixed point under the ground. 
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 —— 求矩形交体积 线段树 + 扫描线 + 离散化的更多相关文章

  1. HDU1255 覆盖的面积 —— 求矩形交面积 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1255 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<= ...

  2. HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...

  3. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

  4. POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)

    题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...

  5. hdu 4419 线段树 扫描线 离散化 矩形面积

    //离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...

  6. POJ1177 Picture —— 求矩形并的周长 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/POJ-1177 A number of rectangular posters, photographs and other pict ...

  7. poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)

    题目链接 题意:给出n个矩形,每个矩形给左下 和 右上的坐标,求围成的周长的长度. 分析: 首先感谢大神的博客,最近做题经常看大神的博客:http://www.cnblogs.com/kuangbin ...

  8. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

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

  9. 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积

    #include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...

随机推荐

  1. Android开发——GPS定位

    1.LocationManager LocationManager系统服务是位置服务的核心组件,它提供了一系列方法来处理与位置相关的问题. 与LocationManager相关的两个知识点: 1.1 ...

  2. OO第二单元博客

    三次作业的设计策略 第一次作业 多线程协同控制 第一次作业只需要两个线程和一个公共缓冲区: 负责读取输入并把它添加进命令队列的线程,即生产者 负责从命令队列中取出命令执行的线程,即消费者 再加上一个缓 ...

  3. 【转】阿里巴巴分布式服务框架 Dubbo 团队成员梁飞专访

    原文链接:http://www.iteye.com/magazines/103   Dubbo是阿里巴巴内部的SOA服务化治理方案的核心框架,每天为2000+ 个服务提供3,000,000,000+ ...

  4. IDEA maven 无法加载已经安装的模块依赖包

    今天打包一直报如下错误 Reactor Summary for freechain-op 1.0.1.OP: [INFO] [INFO] freechain-op .................. ...

  5. Leetcode 313.超级丑数

    超级丑数 编写一段程序来查找第n个超级丑数. 超级丑数是指其所有质因数都是长度为 k 的质数列表 primes 中的正整数. 示例: 输入: n = 12, primes = [2,7,13,19] ...

  6. K/3Cloud二次开发基于WebDev附加进程调试

    大部分人在进行K/3cloud二次开发插件的调试时,选择的是附加IIS进程w3wp调试,本文给大家介绍一下基于WebDev附加进程调试,不用重启iis. 步骤如下: 1)拷贝K/3cloud产品安装目 ...

  7. Circling Round Treasures(codeforces 375c)

    题意:要求在一张网格图上走出一条闭合路径,不得将炸弹包围进去,使围出的总价值减去路径长度最大. /* 类似于poj3182的做法,只不过出现了多个点,那么就用状态压缩的方法记录一个集合即可. */ # ...

  8. [NOIP2003] 提高组 洛谷P1039 侦探推理

    题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明 ...

  9. Java线程的5种状态及切换(透彻讲解)

    http://blog.csdn.net/pange1991/article/details/53860651

  10. Eclipse通过Maven构建时出现: Fatal error compiling: tools.jar not found: Fatal error compiling: tools.jar not found: C:\Program Files\Java\jre1.8.0_31\..\lib\tools.jar

    错误: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile (default-com ...