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. OpenWrt网络结构

    原文链接:http://www.freezhongzi.info/?p=104 OpenWrt网络结构 OpenWrt的网络配置很丰富,在我看来几乎可以完成任何网络结构.下图为一个支持OpenWrt的 ...

  2. Delphi 程序结构

    注:该内容整理自以下链接. http://www.cnblogs.com/hackpig/archive/2010/02/15/1668513.html 概要介绍:Object Pascal语言的结构 ...

  3. iOS 开发之照片框架详解(1)

    http://kayosite.com/ios-development-and-detail-of-photo-framework.html/comment-page-1 一. 概要 在 iOS 设备 ...

  4. Maven——聚合与继承

    原文:http://www.cnblogs.com/xdp-gacl/p/4058008.html 一.聚合 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合 1.1.聚合配置代码 ...

  5. Sqlserver_视图

    SQL CREATE VIEW 语句 在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表. 视图包含行和列,就像一个真实的表.视图中的字段就是来自一个或多个数据库中的真实的表中的字段. 您可 ...

  6. 转!!Java垃圾回收机制

    1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...

  7. request获取ip数据

    http://www.cnblogs.com/icerainsoft/p/3584532.html

  8. commonJS — 字符串操作(for String)

    for String github: https://github.com/laixiangran/commonJS/blob/master/src/forString.js 代码 /** * Cre ...

  9. 网页上记录鼠标的点击次数和一段有用的php代码,自己学习使用

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. 理解Cookie和Session机制

    转载: 理解Cookie和Session机制 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录 ...