18233 万湖之国的形成
时间限制:2500MS 内存限制:65535K
提交次数:0 通过次数:0题型: 编程题 语言: G++;GCC;VC
Description
N国原是一块平原上,没有湖,直到一颗小行星撞入大气层碎成成千上万的碎片,碎片再撞击地面形成 一个一个的坑, 下雨之后,最终形成万湖之国。 现在科学家想用计算机模拟万湖之国形成过程,假设每一块碎片撞击地面,都撞出一个园形坑,现在知道 每一个碎片造成的坑的圆心和半径,问每个坑都注满水后,最终形成多少个湖
输入格式
第一行一个整数N,1<=N<=100,000,表示坑的数量 此后N行,每一行三个double实数,前两个数是圆心的坐标x和y,最后一个数是圆半径(不大于1000) (数据随机产生,分布均匀)
输出格式
湖的个数
输入样例
3 0 0 5 10 0 5 11.1 0 2.5
输出样例
2
#include <iostream>//!!万湖之国
#include <algorithm>
using namespace std;
int p[100050];
struct circle
{
double x,y;
double r;
} c[100050]; //设置成这个大小的原因
bool com(struct circle a,struct circle b)//每个圆右端点的位置大小,给每个圆排序
{
return a.x+a.r<b.x+b.r ;
}
long long find(int x)
{
if(p[x]==x) return x;
else return p[x]=find(p[x]);
}
int main()
{
long long n;
long long count;
cin >>n;
count=n;
for(int i=0; i<n; i++)
{
cin>>c[i].x>>c[i].y>>c[i].r;
p[i]=i;//!!
}
sort(c,c+n,com);//!!按照圆的右端点位置排序
for(int i=0; i<n; i++)
{
for(int j=i-1; j>=0; j--)//!!和第i个圆的左边的j个圆比较
{
if(c[j].x+c[j].r<=c[i].x-c[i].r) break;//!!第i个圆的左端点横坐标值是否大于前面的第j个圆右端点横坐标值
if(((c[j].x-c[i].x)*(c[j].x-c[i].x)+(c[j].y-c[i].y)*(c[j].y-c[i].y))<(c[j].r+c[i].r)*(c[j].r+c[i].r))//d<r1+r2
{
long long r,l;
r=find(i);
l=find(j);
if(r!=l) count--;//如果两个圆的父结点不同,圆坑数量-1
p[r]=l;//把两个圆坑合为一个,父节点相同
}
}
}
cout << count<< endl;
return 0;
}