惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
IT之家
IT之家
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Security Archives - TechRepublic
Security Archives - TechRepublic
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
P
Palo Alto Networks Blog
Know Your Adversary
Know Your Adversary
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Cisco Talos Blog
Cisco Talos Blog
L
Lohrmann on Cybersecurity
AWS News Blog
AWS News Blog
J
Java Code Geeks
博客园_首页
Scott Helme
Scott Helme
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
T
The Exploit Database - CXSecurity.com
Security Latest
Security Latest
V
Visual Studio Blog
Cloudbric
Cloudbric
Jina AI
Jina AI
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
A
Arctic Wolf
C
Cybersecurity and Infrastructure Security Agency CISA
S
SegmentFault 最新的问题
The Last Watchdog
The Last Watchdog
SecWiki News
SecWiki News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
W
WeLiveSecurity
K
Kaspersky official blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hacker News: Ask HN
Hacker News: Ask HN
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
量子位
Google Online Security Blog
Google Online Security Blog
博客园 - Franky
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - 三生石上(FineUI控件)
Recent Commits to openclaw:main
Recent Commits to openclaw:main

博客园 - woodfish

偏序集的Dilworth定理 XJOJ历经2个月终于完成啦~~ fork()调用的一个趣题 实现google那种输入框提示的功能 POJ 3691 安徽第二题 有限状态自动机+DP 哈尔滨赛区网络预选赛总结 [计算几何]点集中的点能组成多少个正方形 [计算几何]POJ 1556 判断线段相交+Dijkstra [计算几何] POJ 1873 暴力+凸包 [计算几何]POJ 1266 三角形的外接圆 圆的参数方程 POJ 1026 置换群 [计算几何]POJ 1031 计算点对多边形的偏转角度 [计算几何]POJ2079 求点集中面积最大的三角形 [计算几何]POJ3608 求2个不相交凸包的最短距离 [计算几何]凸包的旋转卡壳算法 C++禁止一个类被继承的技术 C与汇编的接口技术 计算位数的3种方法 避免使用条件分支
[计算几何]POJ 1375 点对圆的切线+线段重叠
woodfish · 2008-09-10 · via 博客园 - woodfish

http://acm.pku.edu.cn/JudgeOnline/problem?id=1375

 

题目大意如上图,ceiling上面有个光源,ceiling和floor有一些圆形的管子,要求出最后floor上光源找不到的区域。

比较简单,直接对每个圆求出两条切线,进而求出被这个圆遮挡住的区域(bx,ex)

最后把这些区域按bx排序,然后线性扫描一遍就可以得到不相交的区域了。

PS:这题精度比较重要,另外求点对圆的切线时先求出点和圆心的向量,然后把这个向量顺时针逆时针各旋转一个角度就可以得到切点的坐标了。

#include <stdio.h>
#include 
<math.h>
#include 
<algorithm>
using namespace std;
#define eps 1.0e-6
#define equ(x,y) (fabs(x-y)<eps)struct Point {
    
double x,y;
};
struct tnode {
    
double bx,ex;
};
inline 
bool operator<(const tnode &t1,const tnode& t2) {
    
return t1.bx<t2.bx||(equ(t1.bx,t2.bx)&&t1.ex<t2.ex);
}

tnode ans[

500];

inline 

void swap(double &x,double &y) {
    
double t=x;
    x
=y;
    y
=t;
}
//将向量p逆时针旋转angle角度
Point Rotate(Point p,double angle) {
    Point res;
    res.x
=p.x*cos(angle)-p.y*sin(angle);
    res.y
=p.x*sin(angle)+p.y*cos(angle);
    
return res;
}
//求Poi对圆(o,r)的两个切点result1和result2
void TangentPoint_PC(Point poi,Point o,double r,Point &result1,Point &result2) {
    
double line=sqrt((poi.x-o.x)*(poi.x-o.x)+(poi.y-o.y)*(poi.y-o.y));
    
double angle=acos(r/line);
    Point unitvector,lin;
    lin.x
=poi.x-o.x;
    lin.y
=poi.y-o.y;
    unitvector.x
=lin.x/sqrt(lin.x*lin.x+lin.y*lin.y)*r;
    unitvector.y
=lin.y/sqrt(lin.x*lin.x+lin.y*lin.y)*r;
    result1
=Rotate(unitvector,-angle);
    result2
=Rotate(unitvector,angle);
    result1.x
+=o.x;
    result1.y
+=o.y;
    result2.x
+=o.x;
    result2.y
+=o.y;
    
return;
}
int main() {
    Point bp;
    Point op;
    
double r;
    
int n;
    
while(scanf("%d",&n)!=EOF) {
        
if(n==0continue;
        scanf(
"%lf %lf",&bp.x,&bp.y);
        
for(int i=0;i<n;i++) {
            scanf(
"%lf %lf %lf",&op.x,&op.y,&r);
            Point r1,r2;
            TangentPoint_PC(bp,op,r,r1,r2);
            
double x1=(r1.y*bp.x-r1.x*bp.y)/(r1.y-bp.y);
            
double x2=(r2.y*bp.x-r2.x*bp.y)/(r2.y-bp.y);
            
if(x1>x2) swap(x1,x2);
            ans[i].bx
=x1;
            ans[i].ex
=x2;
        }
        sort(ans,ans
+n);
        printf(
"%.2lf",ans[0].bx);
        
double prevy=ans[0].ex;
        
for(int i=1;i<n;i++) {
            
if(!equ(prevy,ans[i].bx)&&ans[i].bx>prevy) {
                printf(
" %.2lf\n%.2lf",prevy,ans[i].bx);
            }
            
if(prevy<ans[i].ex) prevy=ans[i].ex;
        }
        printf(
" %.2lf\n",prevy);
        putchar(
'\n');
    }
return 0;
}