hdu 3642 Get The Treasury

Get The Treasury

http://acm.hdu.edu.cn/showproblem.php?pid=3642

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

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

2010
Asia Regional Hangzhou Site —— Online Contest

Recommend

lcy   |   We have carefully selected several similar
problems for you:  2871 3308 3641 3397 1540

题意:求n个长方体至少相交3次的体积和

z这一维只有500,所以枚举z轴,然后就相当于二维的扫描线

线段树维护区间完全覆盖1、2、3次的长度

#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
#define N 1001
#define lc k<<1,l,mid
#define rc k<<1|1,mid+1,r
struct node
{
    int l,r,h,f;
    bool operator < (node p)const
    {
        return h<p.h;
    }
}a[N<<1];
struct edge
{
    int x,xx,y,yy,z,zz;
}b[N];
int sum1[N<<3],sum2[N<<3],sum3[N<<3],f[N<<3],has[N<<1],has2[N<<1];
long long ans;
int n,cnt,opl,opr,w;
void up(int k,int l,int r)
{
    if(f[k]>=3) sum3[k]=has2[r+1]-has2[l];
    else if(f[k]==2)
    {
        sum3[k]=sum1[k<<1]+sum1[k<<1|1];
        sum2[k]=has2[r+1]-has2[l];
    }
    else if(f[k]==1)
    {
        sum3[k]=sum2[k<<1]+sum2[k<<1|1];
        sum2[k]=sum1[k<<1]+sum1[k<<1|1];
        sum1[k]=has2[r+1]-has2[l];
    }
    else
    {
        sum3[k]=sum3[k<<1]+sum3[k<<1|1];
        sum2[k]=sum2[k<<1]+sum2[k<<1|1];
        sum1[k]=sum1[k<<1]+sum1[k<<1|1];
    }
}
void change(int k,int l,int r)
{
    if(opl<=l && r<=opr)
    {
        f[k]+=w;
        up(k,l,r);
        return;
    }
    int mid=l+r>>1;
    if(opl<=mid) change(lc);
    if(opr>mid) change(rc);
    up(k,l,r);
}
int main()
{
    int T;
    scanf("%d",&T);
    for(int t=1;t<=T;t++)
    {
        ans=0;
        cnt=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d%d%d%d",&b[i].x,&b[i].y,&b[i].z,&b[i].xx,&b[i].yy,&b[i].zz);
            has[i*2-1]=b[i].z; has[i*2]=b[i].zz;
        }
        sort(has+1,has+2*n+1);
        cnt=unique(has+1,has+2*n+1)-(has+1);
        for(int i=1;i<cnt;i++)
        {
            int sz=0;
            for(int j=1;j<=n;j++)
             if(b[j].z<=has[i] && b[j].zz>=has[i+1])
             {
                 a[++sz].l=b[j].x; a[sz].r=b[j].xx; a[sz].h=b[j].y; a[sz].f=1;
                 a[++sz].l=b[j].x; a[sz].r=b[j].xx; a[sz].h=b[j].yy; a[sz].f=-1;
                 has2[sz-1]=b[j].x; has2[sz]=b[j].xx;
             }
            sort(has2+1,has2+sz+1);
            int m=unique(has2+1,has2+sz+1)-(has2+1);
            sort(a+1,a+sz+1);
            memset(sum1,0,sizeof(sum1));
            memset(sum2,0,sizeof(sum2));
            memset(sum3,0,sizeof(sum3));
            for(int j=1;j<=sz;j++)
            {
                opl=lower_bound(has2+1,has2+m+1,a[j].l)-has2;
                opr=lower_bound(has2+1,has2+m+1,a[j].r)-has2-1;
                w=a[j].f;
                change(1,1,m);
                ans+=1ll*sum3[1]*(a[j+1].h-a[j].h)*(has[i+1]-has[i]);
            }
        }
        printf("Case %d: %I64d\n",t,ans);
    }
}
时间: 2025-01-12 09:42:22

hdu 3642 Get The Treasury的相关文章

hdu 3642 Get The Treasury(扫描线)

题目链接:hdu 3642 Get The Treasury 题目大意:三维坐标系,给定若干的长方体,问说有多少位置被覆盖3次以上. 解题思路:扫描线,将第三维分离出来,就是普通的二维扫描线,然后对于每个节点要维护覆盖0,1,2,3以上这4种的覆盖面积. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const

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

题目大意: 给出N个立方体. 求一个三维空间中被包围三次的空间的体积之和. 思路分析: 发现Z的范围很小.那么我们可以枚举Z轴,然后对 x y做扫描线. 而且不用枚举所有的Z ,只需要将Z离散化之后枚举. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define maxn 2222 #define debug puts("fuck!&q

HDU 3642 Get The Treasury 线段树+扫描线

反向标记是错的,要对矩形进行拆分 #include <cstdio> #include <algorithm> #include <cstring> #include <vector> typedef long long LL; using namespace std; #define lson rt << 1,l,mid #define rson rt << 1 | 1,mid + 1,r const int maxn = 5e4

HDU 3642 Get The Treasury(线段树)

HDU 3642 Get The Treasury 题目链接 题意:给定一些立方体,求体积重叠超过3次的 思路:由于z坐标只有500,那么就可以枚举z坐标,每次做x,y的面积并即可,用线段树维护 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1005; const int INF = 0x3f3f3f3f; typedef

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description Jack knows that there is a great underground treasury in a secret region. And he has a special d

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

题意:给你一些长方体,问你覆盖三次及以上的体积有多大 首先我们观察x轴y轴一样很大,但是z轴很小,所以我们可以枚举z轴(-500,500),注意我们枚举的是每一段长度为一的z轴的xy轴的面积而不是点.接着就是求在这一段内的矩形面积并的变形 注意我们要首先计算,再插入线段求面积并 #include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include&

HDU 3642 线段树+离散化+扫描线

题意:给你N个长方体的左下角和右上角坐标,问你空间中有多少体积是被大于两个不同的立方体覆盖的.x,y~10^6 z~500 考虑到给的z比较小,所以可以直接枚举z,然后跑二维的扫描线就好. 关于处理被不同的线段覆盖三次的问题,可以维护四个信息,cnt,once,twice,more,然后相互推出结果就好. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> #

Q - Get The Treasury - HDU 3642 (扫面线求体积)

题意:求被三个或三个以上立方体重合的体积 分析:就是平面面积的加强,不过归根还是一样的,可以把z轴按照从小向大分区间N个,然后可以得到N个平面,用平面重复三次以上的在和高度计算体积. ************************************************************************ #include<stdio.h>#include<algorithm>using namespace std; #define Lson r<<

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

给出n个立方体,要你求这些立方体至少被覆盖三次的部分. 先把这个立方体的信息存在来,发现Z的范围不大,z范围是是[-500,500],所以我们可以先离散化,然后枚举Z, 然后对于每一段Z的区域内,在当前的区域内对xoy轴使用一次扫描线,找到当前这个区域内被覆盖三次的体积,然后每次枚举Z,每次相加,就是最后的答案. #include<map> #include<set> #include<ctime> #include<cmath> #include<s