【矩形切割】卫星覆盖

卫星覆盖

Cover

 

   SERCOI(Space-EarthResource Cover-Observe lnstitute)是一个致力于利用卫星技术对空间和地球资源进行覆盖观测的组织。现在他们研制成功一种新型资源观测卫星-SERCOI-308。这种卫星可以覆盖空间直角坐标系中一定大小的立方体空间,卫星处于该立方体的中心。

    其中(x,y,z)为立方体的中心点坐标,r为此中心点到立方体各个面的距离(即r为立方体高的一半).立方体的各条边均平行于相应的坐标轴。我们可以用一个四元组(x,y,z,r)描述一颗卫星的状态,它所能覆盖的空间体积。

由于一颗卫星所能覆盖的空间体积是有限的,因此空间中可能有若干颗卫星协同工作。它们所覆盖的空间区域可能有重叠的地方,如下图所示(阴影部分表示重叠的区域)。

写一个程序,根据给定的卫星分布情况,计算它们所覆盖的总体积。

 

输入输出

输入文件是INPU.TXT。文件的第一行是一个正整数N(1<=N<=100):表示空间中的卫星总数。接下来的N行每行给出了一颗卫星的状态,用空格隔开的四个正整数x,y,z,r依次表示了该卫星所能覆盖的立方体空间的中心点坐标和半高,其中-1000<=x,y,z<=1000,1<=r<=200。

                                      输出文件是OUTPUT.TXT。文件只有一行,包

括一个正整数,表示所有这些卫星所覆盖的空间总体积。

 

样例

INPUT.TXT

3

0 0 0 3

1 –1 0 1

19 3 5 6

 

OUTPUT.TXT

1944



求体积并有很多方法,这个矩形切割的方法是最简单,最容易实现的。。其基本思想就是离散化,把所有点离散化出来、、具体实现没有多少可以讲的,很浅显。

很多统计问题都可以用矩形切割来实现。另外矩形切割可以很容易推广到m维,我还没有实现过。


#include <cstdio>

long x1[110];
long x2[110];
long y1[110];
long y2[110];
long z1[110];
long z2[110];

long n;long ans=0;

void Cut(long fx1,long fx2,long fy1,long fy2,long fz1,long fz2,long i)
{
	while (i<n+1&&(fx1>=x2[i]||fx2<=x1[i]||fy1>=y2[i]||fy2<=y1[i]||fz1>=z2[i]||fz2<=z1[i]))
		i++;
	if (i==n+1){ans+=(fx2-fx1)*(fy2-fy1)*(fz2-fz1);return;}
	if (fx1<x1[i]){Cut(fx1,x1[i],fy1,fy2,fz1,fz2,i+1);fx1=x1[i];}
	if (fx2>x2[i]){Cut(x2[i],fx2,fy1,fy2,fz1,fz2,i+1);fx2=x2[i];}
	if (fy1<y1[i]){Cut(fx1,fx2,fy1,y1[i],fz1,fz2,i+1);fy1=y1[i];}
	if (fy2>y2[i]){Cut(fx1,fx2,y2[i],fy2,fz1,fz2,i+1);fy2=y2[i];}
	if (fz1<z1[i]){Cut(fx1,fx2,fy1,fy2,fz1,z1[i],i+1);fz1=z1[i];}
	if (fz2>z2[i]){Cut(fx1,fx2,fy1,fy2,z2[i],fz2,i+1);fz2=z2[i];}
}

int main()
{
	freopen("cover.in","r",stdin);
	freopen("cover.out","w",stdout);
	
	scanf("%ld",&n);
	for (long i=1;i<n+1;i++)
	{
		long xx;long yy;long zz;long rr;
		scanf("%ld%ld%ld%ld",&xx,&yy,&zz,&rr);
		x1[i] = xx-rr; x2[i] = xx+rr;
		y1[i] = yy-rr; y2[i] = yy+rr;
		z1[i] = zz-rr; z2[i] = zz+rr;
	}
	
	for (long i=n;i>0;i--)
	{
		Cut(x1[i],x2[i],y1[i],y2[i],z1[i],z2[i],i+1);
	}
	printf("%ld",ans);
	return 0;	
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值