Get The Treasury

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2190    Accepted Submission(s): 669

Problem Description
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 x1, y1, z1, x2, y2 and z2 (x1<x2, y1<y2, z1<z2). 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 x1 to x2. 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.

 
Input
The 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 x1, y1, z1, x2, y2 and z2, separated by a space. The absolute value of x and y coordinates of the vertices is no more than 106, and that of z coordinate is no more than 500.

 
Output
For 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
 
Source
 
 
题目意思:
给n个立方体,求n个立方体相交三次或三次以上的部分的体积。
 
思路:
扫描线3维的应用,把z离散化,那么每一块z[i]--z[i+1]中相交三次或三次以上的体积就是相交三次或三次以上的面积*(z[i+1]-z[i])。
求出相交三次或三次以上的面积即可。
 
代码:
 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
using namespace std; #define N 1005
#define ll root<<1
#define rr root<<1|1
#define mid (a[root].l+a[root].r)/2 int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
int abs(int x,int y){return x<?-x:x;} struct node{
int l, r;
int one, two, more;
int val;
}a[N*]; struct Line{
int x1, x2, y, val;
Line(){}
Line(int a,int b,int c,int d){
x1=a;
x2=b;
y=c;
val=d;
}
}line[N*]; bool cmp(Line a,Line b){
return a.y<b.y;
} struct spot{
int x1, y1, z1, x2, y2, z2;
}s[N]; int n, nx, nz;
int xx[N*];
int zz[N*]; int b_s(int key){
int l=, r=nx-;
while(l<=r){
int mm=(l+r)/;
if(xx[mm]==key) return mm;
else if(xx[mm]>key) r=mm-;
else if(xx[mm]<key) l=mm+;
}
} void build(int l,int r,int root){
a[root].l=l;
a[root].r=r;
a[root].one=a[root].two=a[root].more=a[root].val=;
if(l==r) return;
build(l,mid,ll);
build(mid+,r,rr);
} void up(int root){
if(a[root].val>) a[root].one=a[root].two=a[root].more=xx[a[root].r+]-xx[a[root].l];
else if(a[root].val==){
a[root].one=a[root].two=xx[a[root].r+]-xx[a[root].l];
if(a[root].l==a[root].r) a[root].more=;
else a[root].more=a[ll].one+a[rr].one;
}
else if(a[root].val==){
a[root].one=xx[a[root].r+]-xx[a[root].l];
if(a[root].l==a[root].r) a[root].two=a[root].more=;
else{
a[root].two=a[ll].one+a[rr].one;
a[root].more=a[ll].two+a[rr].two;
}
}
else{
if(a[root].l==a[root].r) a[root].one=a[root].two=a[root].more=;
else{
a[root].one=a[ll].one+a[rr].one;
a[root].two=a[ll].two+a[rr].two;
a[root].more=a[ll].more+a[rr].more;
}
}
} void update(int l,int r,int val,int root){
if(a[root].l==l&&a[root].r==r){
a[root].val+=val;
up(root);
return;
}
if(r<=a[ll].r) update(l,r,val,ll);
else if(l>=a[rr].l) update(l,r,val,rr);
else{
update(l,mid,val,ll);
update(mid+,r,val,rr);
}
up(root);
} main()
{
int t, i, j, k;
int kase=;
cin>>t;
while(t--){
scanf("%d",&n);
nx=nz=;
for(i=;i<n;i++){
scanf("%d %d %d %d %d %d",&s[i].x1,&s[i].y1,&s[i].z1,&s[i].x2,&s[i].y2,&s[i].z2);
xx[nx++]=s[i].x1;
xx[nx++]=s[i].x2;
zz[nz++]=s[i].z1;
zz[nz++]=s[i].z2;
}
sort(xx,xx+nx);
sort(zz,zz+nz);
nx=unique(xx,xx+nx)-xx;
nz=unique(zz,zz+nz)-zz;
__int64 ans=;
for(i=;i<nz;i++){
k=;
for(j=;j<n;j++){
if(s[j].z1<=zz[i-]&&s[j].z2>=zz[i]){
line[k++]=Line(s[j].x1,s[j].x2,s[j].y1,);
line[k++]=Line(s[j].x1,s[j].x2,s[j].y2,-);
}
}
sort(line,line+k,cmp);
build(,nx,);
__int64 num=;
for(j=;j<k-;j++){
update(b_s(line[j].x1),b_s(line[j].x2)-,line[j].val,);
num+=(__int64)a[].more*(__int64)(line[j+].y-line[j].y);
}
ans+=num*(__int64)(zz[i]-zz[i-]);
}
printf("Case %d: %I64d\n",kase++,ans);
}
}

HDU 3642 扫描线(立方体体积并)的更多相关文章

  1. HDU 3255 扫描线(立方体体积并变形)

    Farming Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  2. hdu 3642 Get The Treasury(扫描线)

    pid=3642" style="">题目链接:hdu 3642 Get The Treasury 题目大意:三维坐标系,给定若干的长方体,问说有多少位置被覆盖3次 ...

  3. Get The Treasury HDU - 3642(体积扫描线)

    给出n个立方体,要你求这些立方体至少被覆盖三次的部分. 先把这个立方体的信息存在来,发现Z的范围不大,z范围是是[-500,500],所以我们可以先离散化,然后枚举Z, 然后对于每一段Z的区域内,在当 ...

  4. Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)

    题意: ...就是求体积交... 解析: 把每一层z抽出来,计算面积交, 然后加起来即可..! 去看一下 二维面积交的代码 再看看这个三维面积交的代码.. down函数里 你发现了什么规律!!! 参考 ...

  5. HDU 3642 - Get The Treasury - [加强版扫描线+线段树]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Others) Memory L ...

  6. HDU 3642 Get The Treasury (线段树扫描线,求体积并)

    参考链接 : http://blog.csdn.net/zxy_snow/article/details/6870127 题意:给你n个立方体,求覆盖三次以上(包括三次)的区域的体积 思路:先将z坐标 ...

  7. hdu 3642 Get The Treasury (三维的扫描线)

    题目大意: 给出N个立方体. 求一个三维空间中被包围三次的空间的体积之和. 思路分析: 发现Z的范围非常小.那么我们能够枚举Z轴,然后对 x y做扫描线. 并且不用枚举全部的Z ,仅仅须要将Z离散化之 ...

  8. hdu 3642 覆盖3次以上体积

    http://www.cnblogs.com/kane0526/archive/2013/03/06/2947118.html 题目大意:给你n个立方体,求相交区域大于等于三次的体积和. 这题需要前面 ...

  9. HDU 3642 Get The Treasury (线段树扫描线)

    题意:给你一些长方体,问你覆盖三次及以上的体积有多大 首先我们观察x轴y轴一样很大,但是z轴很小,所以我们可以枚举z轴(-500,500),注意我们枚举的是每一段长度为一的z轴的xy轴的面积而不是点. ...

随机推荐

  1. 没办法,还是要补一下js,回调函数(转载)

    <html> <head> <title>回调函数(callback)</title> <script language="javasc ...

  2. 12 Using_explain_plan

    The row source tree is the core of the execution plan. The tree shows the following information: An ...

  3. javaMail编写案列

    package common.impl; import java.util.Properties; import javax.mail.BodyPart; import javax.mail.Mess ...

  4. oracle 性能优化建议小结

    原则一:注意WHERE子句中的连接顺序: ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHER ...

  5. Android spinner控件

    spinner控件是Android中下拉控件,现在介绍它两种用法.第一种,从资源文件中获取下拉值:第二种,从代码中获取下拉值. 第一种,首先要在资源文件中把值写好: <?xml version= ...

  6. maven实战_01_搭建maven开发环境

    一 下载maven 在maven官网上可下载maven:http://maven.apache.org/download.cgi 下载好后,解压.我的解压到了:D:\maven\apache-mave ...

  7. 怎么进入BAT的研发部门?

    怎么进入BAT的研发部门? ======================================剑指offer+leetcode+geeksforgeeks+编程之美+算法导论====秒杀BA ...

  8. JSON和JSONP区别和联系

    由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socket通讯 ...

  9. switch-case 执行顺序

    switch(expression){ case value : //语句 break; //可选 case value : //语句 break; //可选 //你可以有任意数量的case语句 de ...

  10. Question store (Repeated review)

    题目36 - ACM在线评测系统http://acm.nyist.net/JudgeOnline/problem.php?pid=36 用户名密码INVATION  讲道理太卡 第一:要注意不同的函数 ...