当前位置: 首页 > news >正文

计算圆的包含(两两圆不相交)

问题

给出\(n\)个圆,求每个圆被哪个圆直接包含(两两圆不相交),如果\(A\)直接包含\(B\),就是不存在\(C\)使得\(A\)包含\(C\)\(C\)包含\(B\)

算法1

lzhorz。

直接用K-D树,暴力解决此问题。

算法2

利用扫描线是一个很好的思路,下面我用的都是垂直的扫描线。

一开始我想把一个圆覆盖\(Y\)轴的部分堆加,当加入一个圆时判断它的圆心是被哪个最上面的部分覆盖。不过这样很容易画出反例:

282105032557770.png

按照上面判断的方法,绿色的圆会被误判为被褐色的圆覆盖。

新的方法

lhorz。

把圆拆成两个部分,一个上弧,一个下弧。

判断一个新加入的圆\(A\)被哪个圆直接包含,可以找到离这个圆最近(但必须在这个圆的上面)一个弧,然后我们就得到了这个弧的“主人”圆\(B\),如果这个弧是上弧,说明圆\(B\)包含圆\(A\);如果是下弧,则说明直接包含圆\(B\)的圆\(C\) 直接包含了圆\(A\)

代码非常好写,但是我调试了近半小时QAQ。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <assert.h>
#include <vector>
using namespace std;

typedef long long i64;

const int MAXN = (int) 1e5 + 3;
const double EPS = 1e-8;

template <class T>
T sqr(const T &x) {
    return x * x;
}

struct Circle {
    int x, y, r;

    void read() {
        scanf("%d%d%d", &x, &y, &r);
    }
};

int n;
Circle A[MAXN];
int fa[MAXN];

int globalX;

double calc(const pair<int, int> &a) {
    return (double) A[a.first].y +
        sqrt(sqr((i64) A[a.first].r) - sqr((i64) A[a.first].x - globalX)) *
        a.second;
}

struct cmp {
    bool operator () (const pair<int, int> &a, const pair<int, int> &b) {
        double tmp = calc(a) - calc(b);
        if (fabs(tmp) > EPS) return tmp < 0;
        return a < b;
    }
};

int main() {
    freopen("kendo.in", "r", stdin);
    freopen("kendo.out", "w", stdout);

    scanf("%d", &n);
    vector< pair<pair<int, int>, int> > key;
    for (int i = 0; i < n; i ++) {
        A[i].read();
        key.push_back(make_pair(make_pair(A[i].x - A[i].r, 1), i));
        key.push_back(make_pair(make_pair(A[i].x + A[i].r, -1), i));
    }
    sort(key.begin(), key.end());

    set< pair<int, int>, cmp> mySet;
    fill(fa, fa + n, -1);
    for (int i = 0, _i = key.size(); i < _i; i ++) {
        int j = key[i].second;
        globalX = key[i].first.first;
        if (key[i].first.second == 1) {
            set< pair<int, int> >::iterator tmp = mySet.lower_bound(make_pair(j, 1));
            if (tmp != mySet.end()) {
                if (tmp->second == -1) fa[j] = fa[tmp->first];
                else fa[j] = tmp->first;
            }
            mySet.insert(make_pair(j, 1));
            mySet.insert(make_pair(j, -1));
        }
        else {
            mySet.erase(make_pair(j, 1));
            mySet.erase(make_pair(j, -1));
        }
    }
    
    return 0;
}

注:答案存放在fa数组。

转载于:https://www.cnblogs.com/wangck/p/4464044.html

相关文章:

  • cacti安装文档
  • [C++参考]拷贝构造函数的参数必须是引用类型
  • 抓虫记之七:模拟鼠标移动就报错
  • 关于全功能团队及测试人员的发展
  • linux 中RPM安装包的安装
  • shiro简单配置
  • 计划从明年暑假开始,带着宝宝做生意
  • ActiveReports 6.0 - 高效开发UI
  • IOS Devices Version
  • C#文件操作大全
  • SQL Server 2012:SQL Server体系结构——一个查询的生命周期(第3部分)(完结)...
  • Arguments的使用
  • Web服务器磁盘满故障深入解析
  • 在shell脚本中调用另一个脚本的三种不同方法(fork, exec, source)
  • ActionScript3游戏中的图像编程(连载十七)
  • [译] React v16.8: 含有Hooks的版本
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • CSS盒模型深入
  • Mocha测试初探
  • mysql外键的使用
  • PHP的Ev教程三(Periodic watcher)
  • SegmentFault 2015 Top Rank
  • vue-cli3搭建项目
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • zookeeper系列(七)实战分布式命名服务
  • 记一次用 NodeJs 实现模拟登录的思路
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 提醒我喝水chrome插件开发指南
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 责任链模式的两种实现
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • k8s使用glusterfs实现动态持久化存储
  • 关于Android全面屏虚拟导航栏的适配总结
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • #1015 : KMP算法
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • (3)(3.5) 遥测无线电区域条例
  • (六)vue-router+UI组件库
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (译)计算距离、方位和更多经纬度之间的点
  • (轉貼) UML中文FAQ (OO) (UML)
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • .htaccess配置常用技巧
  • .NET Framework 服务实现监控可观测性最佳实践
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • .sh 的运行
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码
  • [AIGC] Redis基础命令集详细介绍
  • [android] 请求码和结果码的作用
  • [AR]Vumark(下一代条形码)