hdu 4214 Crash and Go(relians)

/*
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;
}


posted @ 2013-04-06 22:44  坚固66  阅读(188)  评论(0编辑  收藏  举报