题目描述

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

现在,在这个地区露出水面的有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. NSQ(7)-nsq存在的问题

    nsq存在的缺陷 部署的难度 ​ nsq提供了一种消费者端进行服务发现的模型,所以无需告诉消费者去哪寻找对于的主题(Topic)在哪个nsqd实例上. ​ 然而,它并没有提供一种方案去解决一个生产者应 ...

  2. onActivityResult 解耦 不需要一层一层的写

    public abstract class AbsShareMessageTemplates implements IShareMessageTemplates { public final stat ...

  3. C++ 函数类型和函数指针类型的自动推导、声明和赋值

    1.函数类型推导 #include <iostream> bool MyComp(int val1, int val2) { return val1 > val2; } int ma ...

  4. clickhouse 重启,软连接失效,增加存储路径

    1. 启动停止命令 systemctl start clickhouse-server systemctl stop clickhouse-server systemctl status clickh ...

  5. 远程ubuntu虚拟机(VirtualBox)

    环境 实机win10,虚拟软件是Oracle VM VirtualBox 下载地址https://www.virtualbox.org/ ubuntu虚拟机配置 网络选桥接网卡, 原因是桥接网卡下,根 ...

  6. Java lombok包中的常用注解,便捷化开发POJO类

    lombok包中的一些常用注解 如何使用Lombok?Lombok提供注解方式来提高代码的简洁性,常用注解有:    @Data    @Setter @Getter    @NonNull    @ ...

  7. 火爆全球的“饺子皮”3D手办原来是这样做的!关键时刻少不了远程控制软件!

    2022年卡塔尔世界杯的吉祥物最近在全球火出圈了,并且喜提中国网友给予的爱称"饺子皮"."馄饨皮"(官方名字:拉伊卜,意为"技艺高超的球员" ...

  8. pgsql查询结果生成序列

    一.row_number生成序列 select (row_number() over()) as id from generate_series(1,100) 二.根据指定列排序 select (ro ...

  9. dp泄露

    DP泄露 选了三道与RSA的dp泄露有关的题,dp泄露算是比较有辨识度的题型. 目录 DP泄露 原理 ctfshow funnyrsa3 分析 解答 BUUCTF RSA2 分析 解答 [羊城杯 20 ...

  10. PHP 阿里云短信验证码的实现

    Test.php是测试你的环境是否部署完成 demo里的sendSms.php里修改 // fixme 必填: 请参阅 https://ak-console.aliyun.com/ 取得您的AK信息$ ...