/* hdu 4214 Crash and Go(relians) 题意:伞兵降落到一个星球上,每个人带着一个电台,只要任何一方进入另一方的覆盖范围,双方就可以沟通 练习到所有可以联系的战友,他们会在一个点()回合,用他们的电台合成一个功率更大的电台,新电台的覆盖面积是那些的和 一直这样合并下去,问最后剩下几个电台 所给数据的顺序就是伞兵落地的顺序,只有落地后才能打开电台 */ #include<stdio.h> #include<list> #include<cmath> #include<iostream> using namespace std; struct node//描述一个电台 的坐标和 覆盖半径 { double a,b,r; }; int he(node &nod,list<node> &ll) { int flag=0;//可合并的个数 double a=0,b=0,rr=0; list<node>::iterator it; it=ll.begin(); while(it!=ll.end()) { double ma=it->a,mb=it->b,mr=it->r; double dist=sqrt((nod.a-ma)*(nod.a-ma)+(nod.b-mb)*(nod.b-mb)); if(dist>mr&&dist>nod.r)//任何一方都未进入另一方的覆盖范围 { it++; continue; }else { a+=ma;//收集可合并的信息 b+=mb; rr+=mr*mr; flag++; it=ll.erase(it);//删除这个电台 } } if(flag)//若可合并 { flag++; a+=nod.a; b+=nod.b; rr+=nod.r*nod.r; a=a/flag; b=b/flag; rr=sqrt(rr); nod.a=a;//合并成新的电台 nod.b=b; nod.r=rr; return 1; }else { return 0;//否则返回0,表示不能合并 } } int main() { int n,i; double a,b,rr; while(cin>>n,n) { list<node> ll; node nod; for(i=1;i<=n;++i) { int flag=0; a=b=rr=0; cin>>nod.a>>nod.b>>nod.r;//读入一个电台(士兵)的信息 while(he(nod,ll))//尝试与其他的电台合并,若合并成功,拿新的电台再次尝试 ;//这儿什么都不做 ll.push_back(nod);//把这个电台放到这里边 } cout<<ll.size()<<endl; } return 0; }