●UVA 10674 Tangents
题链:
https://vjudge.net/problem/UVA-10674
题解:
计算几何,求两个圆的公切线。
《算法竞赛入门经典——训练指南》P266,讲得很清楚的。
大致是分为6种情况——内含,重合,内切,相交,外切,相离这六个情况去处理,
找到共通点,便于代码编写。
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-8;
const double Pi=acos(-1);
int sign(double x){
if(fabs(x)<=eps) return 0;
return x<0?-1:1;
}
struct Point{
double x,y;
Point(double _x=0,double _y=0):x(_x),y(_y){}
void Read(){scanf("%lf%lf",&x,&y);}
};
struct Circle{
Point o; double r;
Point GP(double a){//Get_Point
return Point(o.x+r*cos(a),o.y+r*sin(a));
}
}C1,C2;
struct Intersect{
Point P[2];
bool operator <(const Intersect &rtm) const{
return sign(P[0].x-rtm.P[0].x)<0||(sign(P[0].x-rtm.P[0].x)==0&&sign(P[0].y-rtm.P[0].y)<0);
}
}ANS[7];
typedef Point Vector;
Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
Vector operator - (Point A,Point B){return Vector(A.x-B.x,A.y-B.y);}
Vector operator * (Point A,double p){return Vector(A.x*p,A.y*p);}
double operator ^ (Vector A,Vector B){return A.x*B.y-A.y*B.x;}
double operator * (Vector A,Vector B){return A.x*B.x+A.y*B.y;}
double GPA(Vector A){//Get_Polar_Angle
return atan2(A.y,A.x);
}
double GL(Vector A){//Get_Length
return sqrt(A*A);
}
int GCCI(Circle A,Circle B){//Get_Circle_Circle_Intersection
int cnt=0,a=0,b=1;
if(A.r<B.r) swap(A,B),swap(a,b);
Vector u=B.o-A.o;
double d=GL(u),rdec=A.r-B.r,radd=A.r+B.r;
if(sign(d-rdec)<0) return 0; //内含
if(sign(d)==0&&A.r==B.r) return -1; //重合,无线多
double base=GPA(u);
if(sign(d-rdec)==0){ //内切
ANS[++cnt].P[a]=A.GP(base); ANS[cnt].P[b]=B.GP(base);
return cnt;
}
double da=acos((A.r-B.r)/d); //2条外公切线
ANS[++cnt].P[a]=A.GP(base+da); ANS[cnt].P[b]=B.GP(base+da);
ANS[++cnt].P[a]=A.GP(base-da); ANS[cnt].P[b]=B.GP(base-da);
if(sign(d-radd)==0){ //1条内公切线
ANS[++cnt].P[a]=A.GP(base); ANS[cnt].P[b]=B.GP(base+Pi);
}
else if(sign(d-radd)>0){ //2条内公切线
da=acos((A.r+B.r)/d);
ANS[++cnt].P[a]=A.GP(base+da); ANS[cnt].P[b]=B.GP(base+da+Pi);
ANS[++cnt].P[a]=A.GP(base-da); ANS[cnt].P[b]=B.GP(base-da+Pi);
}
return cnt;
}
int main(){
int cnt;
while(1){
C1.o.Read(); scanf("%lf",&C1.r);
C2.o.Read(); scanf("%lf",&C2.r);
if(!C1.o.x&&!C1.o.y&&!C1.r&&!C2.o.x&&!C2.o.y&&!C2.r) break;
cnt=GCCI(C1,C2);
printf("%d\n",cnt);
if(cnt<=0) continue;
sort(ANS+1,ANS+cnt+1);
for(int i=1;i<=cnt;i++){
printf("%.5lf %.5lf %.5lf %.5lf %.5lf\n",ANS[i].P[0].x,ANS[i].P[0].y,ANS[i].P[1].x,ANS[i].P[1].y,GL(ANS[i].P[1]-ANS[i].P[0]));
} }
return 0;
}
●UVA 10674 Tangents的更多相关文章
- UVa 10674 (求两圆公切线) Tangents
题意: 给出两个圆的圆心坐标和半径,求这两个圆的公切线切点的坐标及对应线段长度.若两圆重合,有无数条公切线则输出-1. 输出是按照一定顺序输出的. 分析: 首先情况比较多,要一一判断,不要漏掉. 如果 ...
- 一位学长的ACM总结(感触颇深)
发信人: fennec (fennec), 信区: Algorithm 标 题: acm 总结 by fennec 发信站: 吉林大学牡丹园站 (Wed Dec 8 16:27:55 2004) AC ...
- .Uva&LA部分题目代码
1.LA 5694 Adding New Machine 关键词:数据结构,线段树,扫描线(FIFO) #include <algorithm> #include <cstdio&g ...
- uva 1354 Mobile Computing ——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5
- UVA 10564 Paths through the Hourglass[DP 打印]
UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...
- UVA 11404 Palindromic Subsequence[DP LCS 打印]
UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求L ...
- UVA&&POJ离散概率与数学期望入门练习[4]
POJ3869 Headshot 题意:给出左轮手枪的子弹序列,打了一枪没子弹,要使下一枪也没子弹概率最大应该rotate还是shoot 条件概率,|00|/(|00|+|01|)和|0|/n谁大的问 ...
- UVA计数方法练习[3]
UVA - 11538 Chess Queen 题意:n*m放置两个互相攻击的后的方案数 分开讨论行 列 两条对角线 一个求和式 可以化简后计算 // // main.cpp // uva11538 ...
- UVA数学入门训练Round1[6]
UVA - 11388 GCD LCM 题意:输入g和l,找到a和b,gcd(a,b)=g,lacm(a,b)=l,a<b且a最小 g不能整除l时无解,否则一定g,l最小 #include &l ...
随机推荐
- raid5 / raid5e / raid5ee的性能对比及其数据恢复原理
RAID 5 是一种存储性能.数据安全和存储成本兼顾的存储解决方案. RAID 5可以理解为是RAID 0和RAID 1的折中方案.RAID 5可以为系统提供数据安全保障,但保障程度要比Mirror低 ...
- SpringMVC源码情操陶冶#task-executor解析器
承接Spring源码情操陶冶-自定义节点的解析.线程池是jdk的一个很重要的概念,在很多的场景都会应用到,多用于处理多任务的并发处理,此处借由spring整合jdk的cocurrent包的方式来进行深 ...
- 流程控制语句(MySQL/MariaDB )
本文目录:1.BEGIN...END2.true和false3.if结构4.case结构5.loop.leave和iterate6.repeat循环7.while循环 MySQL/MariaDB中的符 ...
- HTTP请求到爬虫代码的终南捷径
前阵子在做爬虫的时候学会了各种抓包,看到http请求的时候硬拼代码实在有点累. 后来发现Postman工具是直接可以把Postman请求直接生成对应的代码,这样一下来就美滋滋了. 那么最后的问题就成了 ...
- wordpress怎么禁止文章复制
登陆你的网站后台--点击菜单栏的"外观"--点击"编辑"--在右侧,找到footer.php,打开它--在</body>之前加入以下代码: 1.禁止 ...
- 新概念英语(1-7)Are you a teacher?
What is Robert's job? A:I am a new student. My name is Robert. B:Nice to meet you. My name's Sophie. ...
- HTML5的常用新特性你必须知道
HTML5的常用新特性你必须知道 1 新的 声明 HTML 有多个不同的版本,只有完全明白页面中使用的确切 HTML 版本,浏览器才能完全正确地显示出 HTML 页面.这就是 的用处. 不是 HTML ...
- vue2.0+koa2+mongodb实现注册登录
前言 前段时间和公司一个由技术转产品的同事探讨他的职业道路,对我说了一句深以为然的话: "不要把自己禁锢在某一个领域,技术到产品的转变,首先就是思维上的转变.你一直做前端,数据的交互你只知道 ...
- 浅谈Web网站的架构演变过程
前言 我们以javaweb为例,来搭建一个简单的电商系统,看看这个系统可以如何一步步演变. 该系统具备的功能: 用户模块:用户注册和管理 商品模块:商品展示和管理 交易模块:创建交易和管理 阶 ...
- 详解Ajax请求(三)——jQuery对Ajax的实现及serialize()函数对于表单域控件参数提交的使用技巧
原生的Ajax对于异步请求的实现并不好用,特别是不同的浏览器对于Ajax的实现并不完全相同,这就意味着你使用原生的Ajax做异步请求要兼顾浏览器的兼容性问题,对于java程序员来讲这是比较头疼的事情, ...