【洛谷 2504】聪明的猴子

题目描述

在一个热带雨林中生存着一群猴子,它们以树上的果子为生。昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水面上。猴子不会游泳,但跳跃能力比较强,它们仍然可以在露出水面的不同树冠上来回穿梭,以找到喜欢吃的果实。

现在,在这个地区露出水面的有N棵树,假设每棵树本身的直径都很小,可以忽略不计。我们在这块区域上建立直角坐标系,则每一棵树的位置由其所对应的坐标表示(任意两棵树的坐标都不相同)。

在这个地区住着的猴子有M个,下雨时,它们都躲到了茂密高大的树冠中,没有被大水冲走。由于各个猴子的年龄不同、身体素质不同,它们跳跃的能力不同。有的猴子跳跃的距离比较远(当然也可以跳到较近的树上),而有些猴子跳跃的距离就比较近。这些猴子非常聪明,它们通过目测就可以准确地判断出自己能否跳到对面的树上。

【问题】现已知猴子的数量及每一个猴子的最大跳跃距离,还知道露出水面的每一棵树的坐标,你的任务是统计有多少个猴子可以在这个地区露出水面的所有树冠上觅食。

输入格式

输入文件monkey.in包括:

第1行为一个整数,表示猴子的个数M(2<=M<=500);

第2行为M个整数,依次表示猴子的最大跳跃距离(每个整数值在1--1000之间);

第3行为一个整数表示树的总棵数N(2<=N<=1000);

第4行至第N+3行为N棵树的坐标(横纵坐标均为整数,范围为:-1000--1000)。

(同一行的整数间用空格分开)

输出格式

输出文件monkey.out包括一个整数,表示可以在这个地区的所有树冠上觅食的猴子数。

输入输出样例

输入 #1
4
 1 2 3 4
6
0 0
1 0
1 2
-1 -1
-2 0
2 2
输出 #1
3

说明/提示

【数据规模】

对于40%的数据,保证有2<=N <=100,1<=M<=100

对于全部的数据,保证有2<=N <= 1000,1<=M=500

感谢@charlie003 修正数据

题解:板子kruskal,可惜我一开始数组开小了,导致50分,RE了另外5个点

           而且我一开始忘记fa[i]=i了。枯了,漏洞百出啊!继续努力。

#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
typedef double db;
const int N=1005;
const int MX=2500006;
int n,m,cp,tot,fa[N],b[N];

struct node{
    int x,y;
}a[N];

struct YCLL{
    int u,v;
    int va;
}e[MX];

int ans=0;

int how_long(int uu,int vv){
    int x5=a[uu].x; int x6=a[vv].x;
    int y5=a[uu].y; int y6=a[vv].y;
    return (x5-x6)*(x5-x6)+(y5-y6)*(y5-y6);
}

bool cmp(YCLL aa,YCLL bb){
    return aa.va<bb.va;
}

int find(int x){
    if(x!=fa[x]) 
       fa[x]=find(fa[x]);
    return fa[x];
}
//int b[N];
int main(){
    freopen("2504.in","r",stdin);
    freopen("2504.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&b[i]);
        scanf("%d",&m);
    for(int i=1;i<=m;i++) fa[i]=i;
    
    for(int i=1;i<=m;i++)
        scanf("%d %d",&a[i].x,&a[i].y);
    for(int i=1;i<=m;i++){
        for(int j=i+1;j<=m;j++){
            cp++; e[cp].u=i; e[cp].v=j;
            e[cp].va=how_long(i,j);
            //cout<<e[cp].va<<endl;
        }
    }
    sort(e+1,e+cp+1,cmp);
    //cout<<cp;
    for(int i=1;i<=cp;i++){
        //cout<<"00340204"<<endl;
        int uu=find(e[i].u);
        int vv=find(e[i].v);
        if(uu==vv) continue;
        
        ans=max(ans,e[i].va); 
        fa[uu]=vv; //tot++;
        //if(tot==(m-1)) break;
    }
    int fans=0; 
    db ff=(db)sqrt(ans);
    for(int i=1;i<=n;i++)
        if(ff<=b[i]) fans++;
    printf("%d",fans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wuhu-JJJ/p/11291216.html
今日推荐