奶酪——并查集,BFS,DFS(NOIP2017提高组)

目录

题目

思路

并查集

代码(java)

BFS(DFS同理)

代码(C++)


题目

思路

        这个题目意思是有很多个球分布在一个三维空间内,如果这些球相切或者相交都可以互相到达,我们需要判断能否通过这些球从底部到达顶部。可以抽象为,所有的球构成了一个图,球即是图中的点,相切或者相交说明两点之间有线。因此我们可以想到,将所有的点组成一个集合,只需要判断这个集合能否到达底部和顶部。

        因此可以使用并查集来组成集合。

        最主要的是这个题n只有1000,因此暴力做也没问题。

并查集

        我们判断每两个球,是否相交或者相切,将所有相切或者相交的球装入到一个集合中去,最后判断是否到达高度为0和n。

        构成集合后,如何判断是否到达 0 和 h?我们可以事先在读入球心数据的时候,判断该球是否与 z = 0 相切或者相交,同样判断是否与 z = h 相切或者相交。

        我这里用 0 表示与第 0 层相交,n+1 表示与第 h 层相交。(因为使用数组下标来表示该球,因此用 n+1 来表示n个球之外的,表示到达h)。

        如果与 0 相交,则 find(i) = 0;与h相交,则 find(i)=n+1;

        最后如果 find(0) == find(n+1) ,则说明可以到达。

        因为需要遍历每两个球,所以时间复杂度是O(n^2)

代码(java)

        注意只有一个球的时候 

import java.io.*;
import java.util.*;

class Main{
    static int N = 1010;
    static int T;
    static int n,h,r;
    static int[] p = new int[N];
    static int[] x = new int[N];
    static int[] y = new int[N];
    static int[] z = new int[N];
    static boolean[] st = new boolean[N];
    public static void main(String[] args) throws IOException{
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        T = Integer.parseInt(in.readLine().split(" ")[0]);
        while(T-->0){
            String[] s = in.readLine().split(" ");
            n = Integer.parseInt(s[0]);
            h = Integer.parseInt(s[1]);
            r = Integer.parseInt(s[2]);
            // 初始化p[]
            for(int i=0;i<=n+1;i++)
                p[i] = i;
            // 读取
            for(int i=1;i<=n;i++){
                s = in.readLine().split(" ");
                x[i] = Integer.parseInt(s[0]);
                y[i] = Integer.parseInt(s[1]);
                z[i] = Integer.parseInt(s[2]);
                if(z[i]+r>=h) p[i] = find(n+1); // 如果连接顶部,将他加到n+1集合
                if(z[i]-r<=0) { // 如果连接底部,其中也同样连接顶部,则直接令find(0)==find(n+1),否则,加到0集合
                    if(p[i]!=i) p[find(0)] = find(n+1);
                    else p[i] = find(0);
                }
            }
            // 构成并查集
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(get(x[i],x[j],y[i],y[j],z[i],z[j])<=4.0*r*r){
                        int pi = find(i);
                        int pj = find(j);
                        if(pi!=pj){
                            p[pi] = pj;
                        }
                    }
                }
            }
            if(find(0)==find(n+1)) System.out.println("Yes");
            else System.out.println("No");
        }
    }
    // 找根节点
    public static int find(int u){
        if(p[u]!=u) p[u] = find(p[u]);
        return p[u];
    }
    // 计算两个圆的路径长度
    public static double get(int x1,int x2,int y1,int y2,int z1,int z2){
         return Math.pow(x1-x2,2)+Math.pow(y1-y2,2)+Math.pow(z1-z2,2);
    }
}

BFS(DFS同理)

        我们可以不事先将所有的球都装入到一个集合,我们直接从最底部的球进行判断,使用bfs向上进行扩展,如果扩展到某个球到达h,说明可以到达。

        相当于是一个多源bfs问题,因为与0相交或者相切的球可能有多个。

        每个球都只需要遍历一遍,但遍历到每个球的时候都需要遍历一遍所有的球,找出其中与当前球相切或者相交的球,然后进行bfs。

        因为每遍历到一个球都需要遍历所有的球,因此时间复杂度也是O(n^2),但是比并查集快,因为如果中途遍历到可以到达 h,则不用再遍历,而并查集要遍历所有的点。

代码(C++)

作者:Conan15
链接:https://www.acwing.com/solution/content/99009/ 

#include <bits/stdc++.h>
using namespace std;
int t, n, h, r, f[1010];
double x[1010], y[1010], z[1010];
inline double dist(double X1, double X2, double Y1, double Y2, double Z1, double Z2) {
    return sqrt((X1 - X2) * (X1 - X2) + (Y1 - Y2) * (Y1 - Y2) + (Z1 - Z2) * (Z1 - Z2));
}

int main() {
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d%d", &n, &h, &r);
        for (int i = 1; i <= n; i++) scanf("%lf%lf%lf", &x[i], &y[i], &z[i]), f[i] = 0;
        queue<int> q; bool ok = 0;
        for (int i = 1; i <= n; i++) 
            if (z[i] <= r) q.push(i), f[i] = 1;
        while (q.size()) {
            int p = q.front(); q.pop();
            if (ok) break;
            if (z[p] + r >= h) {ok = 1; puts("Yes"); break;}
            for (int i = 1; i <= n; i++) {
                if (f[i]) continue;
                if (dist(x[p], x[i], y[p], y[i], z[p], z[i]) <= 2 * r) {
                    q.push(i), f[i] = 1;
                    if (z[i] + r >= h) {ok = 1; puts("Yes"); break;}
                }
            }
        }
        if (!ok) puts("No");
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/555761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

二、e2studio VS STM32CubeIDE之功能对比

目录 一、概述/目的 二、官网资料 2.1 stm32cubeide 2.2 e2studio 三、功能对比 二、e2studio VS STM32CubeIDE之功能对比 一、概述/目的 通过对比学习&#xff0c;更快速的掌握两款IDE 二、官网资料 2.1 stm32cubeide https://www.stmcu.com.cn/ecosystem/Cube/STM32C…

41、二叉树-二叉树的层序遍历

思路&#xff1a; 层序遍历就是从左到右依次遍历。这个时候就可以使用队列的方式。例如先把头节点入队&#xff0c;然后遍历开始&#xff0c;首先计算队列长度&#xff0c;第一层&#xff0c;长度为了&#xff0c;遍历一次&#xff0c;依次出队&#xff0c;头结点出队&#xff…

Codeforces Round 924 (Div. 2) ---- F. Digital Patterns ---- 题解

F. Digital Patterns&#xff1a; 题目描述&#xff1a; 思路解析&#xff1a; 要求在一个方块中&#xff0c;任意相邻的方块中他的透明度系数不能相同&#xff0c;这样的方块称为趣味性方块&#xff0c;问这样的方块有多少种。 那么我们可以相当&#xff0c;假设 a1 a2, 那…

iOS ------ Block的总结

前面看了Block的基本知识&#xff0c;和一些源码。但对于block怎么用的还不了解&#xff0c;代码中出现block会看不懂&#xff0c;现在来具体看一下Block的用法并做个总结。 1.Block是什么 block对象是一个C语言结构体&#xff0c;可以并入C和OC的代码中&#xff0c;Block本质…

每日OJ题_多源BFS①_力扣542. 01 矩阵(多源BFS解决最短路原理)

目录 多源BFS解决最短路算法原理 力扣542. 01 矩阵 解析代码 多源BFS解决最短路算法原理 什么是单源最短路 / 多源最短路&#xff1f; 之前的BFS解决最短路都是解决的单源最短路。 画图来说&#xff0c;单源最短路问题即为&#xff1a; 而对于多源最短路问题: 如何解决此…

微信小程序之点击事件

微信小程序中常用的点击事件主要是 tap&#xff0c;但除此之外还有其他的触摸类事件&#xff0c;用于不同的交互场景。以下是一些常见的点击和触摸相关的事件及其区别&#xff1a; 1、tap——最基本的点击事件&#xff0c;适用于一般的轻触交互&#xff0c;类似于 HTML 中的 c…

Pixverse:开启文生视频与图生视频新纪元

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

NPU流式输出-torch_npu和transformers框架-多线程Streamer-昇腾910B-EE1001

前情提要 torch_npu框架不支持多线程自动set_device 报错详情 直接使用transformers的TextIteratorStreamer进行流式推理&#xff0c;会报错 Exception in thread Thread-6: Traceback (most recent call last):File "/root/anaconda3/envs/AI/lib/python3.9/threadin…

Linux shell 脚本基础与部署SpringCloud实战

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

L2正则化——解释为什么可以减少模型的复杂度

L2正则化是一种用于机器学习模型的技术&#xff0c;旨在减少模型的复杂度&#xff0c;从而提高其泛化能力。在L2正则化中&#xff0c;通过添加一个惩罚项&#xff0c;模型的权重被迫保持较小的值&#xff0c;这有助于防止过拟合&#xff0c;即模型在训练数据上表现良好但在未见…

python学习笔记B-07:序列结构之列表--列表的常用函数和方法

以xx_函数名(列表名)的形式出现的是函数&#xff1b;以xx_列表名.xx_方法名的形式出现的是方法。 列表常用函数如下&#xff1a; len()&#xff1a;计算列表元素数量 max()&#xff1a;获取列表元素最大值 min():获取列表元素最小值 sum():计算列表中各元素之和 列表常用方法如…

【Java EE】文件操作

目录 1.认识文件 2.树型结构组织和目录 3.文件路径&#xff08;Path&#xff09; 4.其他知识 5.Java中操作文件 5.1File概述 5.1.1属性 5.1.2构造方法 5.1.3方法 5.2代码示例 1.认识文件 我们先来认识狭义的文件&#xff08;file&#xff09;。针对1硬盘这种持久化存…

HTML重要标签梳理学习

1、HTML文件的框架 使用VS Code编码时&#xff0c;输入!选中第一个&#xff01;就可以快速生成一个HTML文件框架。 2、标签 <hr> <!--下划线--> <br> <!--换行--> <strong>加粗</strong> &…

MySQL行级锁——技术深度+1

引言 本文是对MySQL行级锁的学习&#xff0c;MySQL一直停留在会用的阶段&#xff0c;需要弄清楚锁和事务的原理并DEBUG查看。 PS:本文涉及到的表结构均可从https://github.com/WeiXiao-Hyy/blog中获取&#xff0c;欢迎Star&#xff01; MySQL行级锁 行级锁&#xff08;Row-…

案例研究 | JumpServer助力天虹股份构建可靠的运维安全审计平台

天虹数科商业股份有限公司&#xff08;以下简称为“天虹股份”&#xff09;成立于1984年&#xff0c;是国有控股的上市公司。通过人本、科学的管理&#xff0c;以及专业、高效的运营&#xff0c;天虹股份连续多年入围中国连锁百强企业&#xff0c;拥有全国领先的零售技术研发和…

vue3 项目启动时vite版本问题报错

背景&#xff1a; 我是在项目迁移过程中遇到的这个问题&#xff0c;前提可以看下面这篇 http://t.csdnimg.cn/g70Eq 问题描述 迁移项目时&#xff0c;将项目整体升级到了vue3版本&#xff0c;启动项目时出现下列报错&#xff1a; npm ERR! Found: vite5.1.4 npm ERR! node_…

2024-2.基础操作-Python

Jupiter基本使用 cell有两种模式&#xff1a; codemarkdown 快捷键 新建cell&#xff1a;a,b删除cell&#xff1a;dd&#xff0c;x运行cell&#xff1a;shiftenter切换cell模式&#xff1a; m&#xff1a;将code模式的cell切换到mdy:将md模式的cell切换到code 智能补全&#x…

QT Webengine开发过程报错qml: Render process exited with code 159 (killed)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、解决方法二、补充说明总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 基于QT的Webengine开发过程中&#xff0c;QT的官方示例…

【算法】反转链表

本题来源---《反转链表》 题目描述&#xff1a; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输…

22长安杯电子取证复现(检材一,二)

检材一 先用VC容器挂载&#xff0c;拿到完整的检材 从检材一入手&#xff0c;火眼创建案件&#xff0c;打开检材一 1.检材1的SHA256值为 计算SHA256值&#xff0c;直接用火眼计算哈希计算 9E48BB2CAE5C1D93BAF572E3646D2ECD26080B70413DC7DC4131F88289F49E34 2.分析检材1&am…