起重机
Accept:20 | Submit:54 |
Time Limit:1000MS | Memory Limit:65536KB |
Description
起重机在现代建筑的建设中起着重要的作用。在一块工地中,通常布置不只一部起重机,我们假设它们的高度一样,由于起重机在空中要旋转,所以两部起重机不能靠得太近,否则就会发生事故。
现在,轮到你来部署一批起重机,使它们能安全运转,并且要使它们覆盖的面积和最大。每部起重机都可覆盖以它为圆心,半径为r的圆形区域。
Input
输入的第一行包含一个整数c,表示测试数据的组数。
每组数据的第一行包含一个整数n表示要备用的起重机的数目(1<=n<=15)。
接下来n行,每行包含三个整数:x,y,r。其中x和y表示可以布置起重机的位置的坐标(-1000<=x,y<=1000),r表示布置在该位置的起重机的覆盖半径。
Output
对每组数据,输出一个整数A,表示最大的覆盖面积为A*π。
Sample Input
1
3
0 0 4
5 0 4
-5 0 4
Sample Output
32
Hint
注意相切时不合法!
/*
思路:
先加入一个圆,然后依次加入各个圆(与已经加入的圆不相交且是最大的)
*/
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct cycle
{
int x,y,r;
}p[20];
int n,c;
int V[20],vcount,ans,sum;
int L[20];
bool Is(cycle a,cycle b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)<=(a.r+b.r)*(a.r+b.r);
}
bool IsAll(cycle a)
{
for(int i=0;i<vcount;i++)
{
if(Is(a,p[V[i]]))return false;
}
return true;
}
int foundmax()
{
int i,j,k;
int MAX=0;
j=-1;
for(i=0;i<n;i++)
{
if(!L[i]&&IsAll(p[i]))
{
k=p[i].r*p[i].r;
if(k>MAX)
{
MAX=k;
j=i;
}
}
}
return j;
}
void solve()
{
int i,j,k;
for(i=0;i<n;i++)
{
memset(L,0,sizeof L);
vcount=0;
V[vcount++]=i;
L[i]=1;
sum=p[i].r*p[i].r;
for(j=1;j<n;j++)
{
k=foundmax();
if(k!=-1)
{
V[vcount++]=k;
sum+=p[k].r*p[k].r;
L[k]=1;
}
else break;
}
if(ans<sum)ans=sum;
}
}
int main()
{
int i,j;
scanf("%d",&c);
while(c--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].r);
}
ans=0;
solve();
printf("%d\n",ans);
}
return 0;
}