HOJ 13102 Super Shuttle
题意:给定一个点 p 和 n 个圆,做某个经过点 p的 圆穿过尽可能多的圆,问可穿过最多的圆是多少。
思路:圆的反演变换:
  给出反演极O和反演幂k>0,作点A的反演点A′。
    令k=r^2,作出反演基圆⊙O(r),
    1)若点A在⊙O(r)外,则过点A作圆的切线(两条),两个切点相连与OA连线交点就是点A′。
    2)若点A在⊙O(r)内,则把上述过程逆过来:连结OA,过点A作直线垂直于OA,直线与⊙O(r)的交点处的切线的交点就是点A′。
    3)若点A在⊙O(r)上,反演点A′就是点A自身。
   推荐看 ACdreamers 的博客 。
  我们取反演点就是点P。如果你看懂了反演,就可以知道,我们所做的圆经过反演变成一条直线(经过点P),而其它圆还是圆, 问题就变成了一条直线穿过尽可能多的圆。当中的tricks 就是反演之后圆可能很大,角度处理细节要注意。
 
代码:
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm> #define op operator
#define db double
#define cn const
#define cp const P&
#define rt return
using namespace std;
cn db pi = acos(-1.0);
cn db eps = 1e-;
const int N = ; inline int sig(db x) {rt (x>eps) - (x<-eps);} int n;
struct P{
db x, y;
P(db _x= , db _y =) : x(_x), y(_y) {}
void in() {scanf("%lf %lf", &x, &y); }
P op-(cp a)cn {rt P(x-a.x, y-a.y); }
P op+(cp a)cn {rt P(x+a.x, y+a.y); }
P op*(db a)cn {rt P(x*a, y*a);}
db dis() {rt sqrt(x*x + y*y);}
};
P p; struct CCL{
P o;
db r;
CCL() {}
CCL(P _o, db _r) : o(_o), r(_r) {}
void in() {o.in(), scanf("%lf", &r); }
}c[N]; CCL Inverse(CCL ci) {
CCL T;
db t = (ci.o - p).dis();
db x = . / (t - ci.r);
db y = . / (t + ci.r);
T.r = (x - y) / 2.0;
db s = (x + y) / 2.0;
T.o = p + (ci.o - p) * (s / t);
rt T;
} struct L{
db alpha;
int t;
L(db a=, int t = ) : alpha(a), t(t) {}
bool op<(cn L& a)cn {
if(sig(alpha - a.alpha)) rt sig(alpha - a.alpha) < ;
rt t > a.t;
}
};
L s[N<<];
int ct; void add_ang(db a1, db a2) {
s[ct++] = L(a1, ), s[ct++] = L(a2, -);
if(sig(a2 - pi) > ) s[ct++] = L(a1-pi-pi, ), s[ct++] = L(a2-pi-pi, -);
if(sig(a1 + pi) < ) s[ct++] = L(a1+pi+pi, ), s[ct++] = L(a2+pi+pi, -);
} void qie(CCL A, CCL B) {
db d = (A.o-B.o).dis();
bool f = ;
db rdiff = A.r - B.r, rsum = A.r + B.r;
if(sig(d + A.r - B.r) <= ) {
s[ct++] = L(-pi-pi, ), s[ct++] = L(pi+pi, -); return ;
}
if(sig(d + B.r - A.r) < ) return ; db base = atan2(B.o.y - A.o.y, B.o.x - A.o.x);
db alpha = acos(rdiff / d); if(sig(d - rsum) <= ) {
add_ang(base - alpha, base + alpha);
} else {
db ang = acos(rsum / d);
add_ang(base - alpha, base - ang);
add_ang(base + ang, base + alpha);
}
} void solve() {
for(int i = ; i < n; ++i) c[i] = Inverse(c[i]); int mx = ;
bool flag = ;
for(int i = ; i < n; ++i) {
ct = , flag = ;
for(int j = ; j < n; ++j) {
if(i == j) continue;
qie(c[i], c[j]);
}
sort(s, s+ct); int mv = ;
for(int j = ; j < ct; ++j) {
mv += s[j].t;
mx = max(mx, mv);
}
}
printf("%d\n", mx+);
} int main()
{
while(scanf("%d", &n) != EOF) {
p.in();
for(int i = ; i < n; ++i) c[i].in();
solve();
}
return ;
}
 
 

HOJ 13102 Super Shuttle (圆的反演变换)的更多相关文章

  1. 圆的反演变换(HDU4773)

    题意:给出两个相离的圆O1,O2和圆外一点P,求构造这样的圆:同时与两个圆相外切,且经过点P,输出圆的圆心和半径 分析:画图很容易看出这样的圆要么存在一个,要么存在两个:此题直接解方程是不容易的,先看 ...

  2. 【 HDU4773 】Problem of Apollonius (圆的反演)

    BUPT2017 wintertraining(15) #5G HDU - 4773 - 2013 Asia Hangzhou Regional Contest problem D 题意 给定两个相离 ...

  3. Pick定理、欧拉公式和圆的反演

    Pick定理.欧拉公式和圆的反演 Tags:高级算法 Pick定理 内容 定点都是整点的多边形,内部整点数为\(innod\),边界整点数\(ednod\),\(S=innod+\frac{ednod ...

  4. 「HDU6158」 The Designer(圆的反演)

    题目链接多校8-1009 HDU - 6158 The Designer 题意 T(<=1200)组,如图在半径R1.R2相内切的圆的差集位置依次绘制1,2,3,到n号圆,求面积之和(n< ...

  5. The Designer (笛卡尔定理+韦达定理 || 圆的反演)

    Nowadays, little haha got a problem from his teacher.His teacher wants to design a big logo for the ...

  6. CF77E Martian Food(圆的反演or 笛卡尔定理+韦达定理)

    题面 传送门 这题有两种方法(然而两种我都想不到) 方法一 前置芝士 笛卡尔定理 我们定义一个圆的曲率为\(k=\pm {1\over r}\),其中\(r\)是圆的半径 若在平面上有两两相切,且六个 ...

  7. 2017多校第6场 HDU 6097 Mindis 计算几何,圆的反演

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6097 题意:有一个圆心在原点的圆,给定圆的半径,给定P.Q两点坐标(PO=QO,P.Q不在圆外),取圆 ...

  8. hdu6158(圆的反演)

    hdu6158 题意 初始有两个圆,按照标号去放圆,问放完 \(n\) 个圆后的总面积. 分析 圆的反演的应用. 参考blog 设反演圆心为 \(O\) 和反演半径 \(R\) 圆的反演的定义: 已知 ...

  9. HDU-4773 Problem of Apollonius (圆的反演)

    参考: https://oi-wiki.org/geometry/inverse/ https://blog.csdn.net/acdreamers/article/details/16966369 ...

随机推荐

  1. 团队博客作业Week3 --- 项目选择&&需求疑问

    项目选择 经过团队内所有成员一致探讨,我们团队选择完善和改进之学霸系统的第二个子模块,即:网站内容结构定义和数据处理.具体的要求如下:(摘自Xueba系统项目需求) 网站内容结构定义和数据处理(Con ...

  2. 2017-2018-2 1723 『Java程序设计』课程 结对编程练习_四则运算

    一.结对对象 姓名:侯泽洋 学号:20172308 担任角色:驾驶员(侯泽洋) 伙伴第一周博客地址 二.本周内容 1.程序需求 (1).自动生成题目 可独立使用(能实现自己编写测试类单独生成题目的功能 ...

  3. java 线程的简单理解

    想要实现线程可以继承Thread也可以实现接口runnable,在类中重写 run()方法在主函数调用start方法就可以开辟线程. 对于java对象都有一个wait()和notify().notif ...

  4. 每天学一点easyui②

    Form插件 <!DOCTYPE html> <html>       <head>         <meta charset="utf-8&qu ...

  5. eclipse异常关闭,而Tomcat然在运行解决方法

    1.eclipse异常关闭,而Tomcat然在运行,再启动tomcat会出现端口冲突 解决方法:打开任务管理器,找到javaw.exe,点击关闭,就可以了

  6. java核心技术卷1知识点

    1.comparable和comparator的区别. Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的. public inte ...

  7. 树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 (五) 树莓派单子节点发送数据

    本项目中各个节点和树莓派的通信不区分信道,因此如果由树莓派发送给特定节点的数据会被所有节点接收到,因此子节点可以判别该数据是否发给自己的,需要在数据的第二个字节中加入目标节点的编号(第一个字节为源节点 ...

  8. 怎样利用好单片机上的存储器资源来实现OD的存储与访问

    转自:http://www.cnblogs.com/winshton/p/4897789.html 我们知道OD(对象字典)是CANopen的核心,所有功能都是围绕它开展的,是协议栈的数据中心,良好的 ...

  9. VS提示“无法启动IIS Express Web服务器”的解决方法

    有时在使用Visual Studio运行项目时,会提示“无法启动IIS Express Web服务器”,如图: 可以依次尝试以下方法(我的情况使用第一种就解决了): 1.可能原因:误操作执行了:Sc ...

  10. flex 布局能解决的问题

    flex 布局,可以解决元素在容器中的对齐.方向.顺序,甚至它们是动态的或者不确定大小的新布局模型.Flex容器的主要特征是能够调整其子元素在不同的屏幕大小中能够用最适合的方法填充合适的空间 . 转载 ...