zoukankan      html  css  js  c++  java
  • 计蒜客 奶酪 (并查集)


    **链接 : ** Here!

    **思路 : **

    • 其实这个是一道简单的并查集问题, 判断$Jerry$是否能从下表面跑到上表面, 其实质上是判断上表面和下表面是否连通, 因此这道问题就变成了判断连通性的问题了. 判断标准是如果$d <= 2 * r$ ($d$为两球心之间的距离), 那么就合并两个集合即可

    **思考 : ** 将知识穿成线索,做等价迁移,将复杂问题变成简单问题.

    **代码 : **

    /*************************************************************************
    	> File Name: t13.cpp
    	> Author: 
    	> Mail: 
    	> Created Time: 2017年11月21日 星期二 16时33分31秒
     ************************************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    using namespace std;
    
    #define MAX_N 1010
    typedef long long ll;
    int par[MAX_N];
    int size[MAX_N];
    ll n, h, r;
    
    struct Point {
        ll x, y, z;
    };
    
    double check(Point a, Point b) {
        return (sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + (a.z - b.z) * (a.z - b.z)) <= 2 * r);
    }
    
    void init() {
        for (int i = 0 ; i < MAX_N ; ++i) {
            par[i] = i;
            size[i] = 1;
        }
    }
    int find(int x) {
        return x == par[x] ? x : (par[x] = find(par[x]));
    }
    void merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return;
        if (size[x] > size[y]) {
            size[x] += size[y];
            par[y] = x;
        } else {
            size[y] += size[x];
            par[x] = y;
        }
    }
    int same(int x, int y) {
        return find(x) == find(y);
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) {
            init();
            Point data[MAX_N];
            scanf("%lld%lld%lld", &n, &h, &r);
            for (int i = 2 ; i <= n + 1 ; ++i) {
                scanf("%lld%lld%lld", &data[i].x, &data[i].y, &data[i].z);
            }
            // 先把能接触到地面的点加入到地面集合0中
            for (int i = 2 ; i <= n + 1 ; ++i) {
                if (fabs(0 - data[i].z) > r) continue;
                if (same(0, i)) continue;    
                merge(0, i);
            }
            // 再把能接触到上端的点加入到顶端集合1中
            for (int i = 2 ; i <= n + 1 ; ++i) {
                if (fabs(h - data[i].z) > r) continue;
                if (same(1, i)) continue;
                merge(1, i);
            }
            
            for (int i = 2 ; i <= n + 1 ; ++i) {
                for (int j = 2 ; j <= n + 1 ; ++j) {
                    if (same(i, j)) continue;
                    if (!check(data[i], data[j])) continue;
                    merge(i, j);
                }
            }
    
            if (same(0, 1)) {
                printf("Yes
    ");
            } else {
                printf("No
    ");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Web端导出CSV
    dojo/dom-style样式操作学习笔记
    dojo/dom源码学习
    上层建筑——DOM元素的特性与属性(dojo/dom-prop)
    上层建筑——DOM元素的特性与属性(dojo/dom-attr)
    返本求源——DOM元素的特性与属性
    DOM扩展札记
    以代码爱好者角度来看AMD与CMD
    dojo事件驱动编程之事件绑定
    通过Web.config中的configSections配置自己系统的全局常量
  • 原文地址:https://www.cnblogs.com/WArobot/p/7883960.html
Copyright © 2011-2022 走看看