题目描述

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

现在,在这个地区露出水面的有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包括一个整数,表示可以在这个地区的所有树冠上觅食的猴子数。

数据范围

2≤N≤1000,1≤M≤500

思路:

这道题是一道使用最小生成树的克鲁斯卡尔算法的题。我们要用最小生成树来将所有节点连接起来,并求出将它连接所需的最小距离。

在这道题中,我们将所有的树冠的位置上设置为端点。在读入的时候,我们设一个结构体来分别存储每个端点的横坐标和纵坐标。记录下每一个端点后,我们可以O(n²)枚举每两个端点,求出这些端点中任意两个点之间的距离(因为所有端点间都可以连接,所以我们可以直接构造一个完全图),并且再开一个结构体来存储每一条边的起点、终点和距离。接下来,我们要对边权从小到大进行排序。

我们维护一个对每个端点的并查集,从边权从小到大加入边,直到边数足够即可退出循环。在建最小生成树的时候,我们要不断更新最小生成树中的最长边的长度。因为我们已经对边权进行了从小到大的排序,所以后加入的边边权一定比前加入的边边权大,故在更新最值时不用比较。

最后求出最值后,我们再对猴子的最大跳跃距离从大到小进行排序,然后进行O(n)的从前往后枚举,如果枚举到一只猴子最大距离小于最大边权,则退出枚举,同时输出当前猴子的序号减1的值(从当前猴子开始无法全跳过)。或者如果已经枚举到了最后一只猴子,则只需要输出这只猴子序号即可,因为所有猴子都能到达所有树冠。

这里不需要判断能否建成最小生成树,因为我们建图时建立的是完全图,保证每两点间都能联通。

另外,在求和判断距离时我们不必求出实际距离,而是求出实际距离的平方,同时在读入猴子最大跳跃距离时对其取平方,这样可以避免精度问题和类型转换。

最后是完整代码:

 1 #include<iostream>
2 #include<algorithm>
3 using namespace std;
4 int m;
5 int dis[505];
6 int n;
7 struct tree{
8 int x,y;
9 }a[1005];
10 int fa[1005];
11 struct street{
12 int start;
13 int end;
14 int val;
15 }b[1000005];
16 bool cmp(street a,street b){
17 return a.val<b.val;
18 }
19 bool cmp2(int a,int b){
20 return a>b;
21 }
22 int find(int x){
23 if(x==fa[x]){
24 return x;
25 }else{
26 return fa[x]=find(fa[x]);
27 }
28 }
29 void unionn(int x,int y){
30 int r1=find(x);
31 int r2=find(y);
32 fa[r1]=r2;
33 }
34 int main(){
35 cin>>m;
36 for(int i=1;i<=m;i++){
37 cin>>dis[i];
38 }
39 sort(dis+1,dis+m+1,cmp2);//从大到小排序
40 cin>>n;
41 for(int i=1;i<=n;i++){
42 cin>>a[i].x>>a[i].y;
43 }
44 int cnt=1;
45 for(int i=1;i<=n;i++){
46 for(int j=i+1;j<=n;j++){
47 b[cnt].start=i;
48 b[cnt].end=j;
49 b[cnt].val=(a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);
50 cnt++;
51 }
52 }
53 cnt--;
54 sort(b+1,b+cnt+1,cmp);
55 for(int i=1;i<=n;i++){
56 fa[i]=i;
57 }
58 int sum=0;
59 int ans=-9999;//加入最小生成树的边的边权最大值
60 for(int i=1;i<=cnt;i++){
61 if(find(b[i].start)!=find(b[i].end)){
62 sum++;
63 ans=max(ans,b[i].val);
64 unionn(b[i].start,b[i].end);
65 }
66 if(sum==n-1){
67 break;
68 }
69 }
70 for(int i=1;i<=m;i++){
71 if(dis[i]*dis[i]<ans){
72 cout<<i-1<<endl;
73 break;
74 }
75 if(i==m){
76 cout<<m<<endl;
77 break;
78 }
79 }
80 return 0;
81 }

P2504 聪明的猴子的更多相关文章

  1. 洛谷—— P2504 [HAOI2006]聪明的猴子

    P2504 [HAOI2006]聪明的猴子 题目描述 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水面上. ...

  2. 洛谷——P2504 [HAOI2006]聪明的猴子

    P2504 [HAOI2006]聪明的猴子 题目描述 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水面上. ...

  3. 洛谷 P2504 [HAOI2006]聪明的猴子

    洛谷 P2504 [HAOI2006]聪明的猴子 题目描述 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着,部分植物的树冠露在水 ...

  4. BZOJ2429[HAOI2006]聪明的猴子[最小生成树 kruskal]

    2429: [HAOI2006]聪明的猴子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 896  Solved: 575[Submit][Statu ...

  5. 最小生成树 2429: [HAOI2006]聪明的猴子

    BZOJ 2429: [HAOI2006]聪明的猴子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 877  Solved: 566[Submit][ ...

  6. [原]携程预选赛A题-聪明的猴子-GCD+DP

    题目: 聪明的猴子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  7. 【解题报告】[动态规划] CodingTrip - 携程编程大赛 (预赛第一场)- 聪明的猴子

    原题: 聪明的猴子 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Problem D ...

  8. 最小生成树——[HAOI2006]聪明的猴子

    题目:[HAOI2006]聪明的猴子 描述: [题目描述] 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着, 猴子不会游泳,但跳 ...

  9. BZOJ 2429: [HAOI2006]聪明的猴子( MST )

    水题, 求MST即可. -------------------------------------------------------------------------------- #includ ...

  10. 2429: [HAOI2006]聪明的猴子

    2429: [HAOI2006]聪明的猴子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 448  Solved: 309[Submit][Statu ...

随机推荐

  1. git将本地文件上传到远程仓库

    要记住! 上传代码之前,一定要先下拉代码,如果有冲突(你和别人同时修改了某一个文件的某一行代码),那么就要先解决冲突,才能提交! 这里以将自己的本地文件上传至git仓库为例 1.首先进入需要上传的文件 ...

  2. facade是如何产生的 in laravel

    据说Facade是为了简化写法, 好记,也有人说要废除这个特性, 据说这个特性有很好的的testability 测试性, 我不清楚, 这个是怎么说出来的理由是什么? 很多Facade 是系统写好的, ...

  3. Python - Numpy 学习笔记

    #python - Numpy learning import numpy as np #---Numpy学习笔记---(第四章)--- #切片,浅拷贝 a = np.arange(10) print ...

  4. [JavaScript]关于prototype继承

    When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private ...

  5. 什么是cache

    什么是cacheTo minimize the quantity of control information stored, the spatial locality property is use ...

  6. php8.0.0新功能:命名参数

    php8.0.0开始引入了命名参数作为现有位置参数的扩展.命名参数允许根据参数名而不是参数位置向函数传参.示例代码: 1 function userInfo($username, $tel, $add ...

  7. SQL 查找是否”存在”,别再用 COUNT 了,真的很费时间!

    根据某一条件从数据库表中查询 『有』与『没有』,只有两种状态,那为什么在写SQL的时候,还要SELECT count(*) 呢?无论是刚入道的程序员新星,还是精湛沙场多年的程序员老手,都是一如既往的c ...

  8. 如何把高德地图搜索结果导出成excel里?

    前段时间,根据朋友的要求,开发了百度地图里的商家采集工具. 最近,又开发了腾讯地图里的商家采集工具. 来了兴致,干脆把高德地图的采集工具也一并搞定!:) 原理应该差不多,我就查阅了下高德地图的采集规则 ...

  9. Flink Application Development DataStream API Operators Overview-- Flink应用程序开发DataStream API操作符概览

    目录 概览 DataStream转换 物理分区 任务链和资源组 翻译原文- Application Development DataStream API Operators 概览 操作符将一个或多个D ...

  10. 【C学习笔记】day2-2 不允许创建临时变量,交换两个数的内容(附加题)

    #include<stdio.h> int main() { int a=0, b=1; int m[2]; m[0] = a; m[1] = b; a = m[1]; b = m[0]; ...