●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 ...
随机推荐
- 【作业】HansBug的前三次OO作业分析与小结
OO课程目前已经进行了三次的作业,容我在本文中做一点微小的工作. 第一次作业 第一次作业由于难度不大,所以笔者程序实际上写的也比较随意一些.(点击就送指导书~) 类图 程序的大致结构如下: 代码分析 ...
- 技术文档分享_linux中生成考核用的GPT分区表结构修复
注:历史版本,后期改用python实现了 实验一: 目的:用于生成大量模拟破坏GPT分区结构案例,并生成唯一方式修复后的评判方法.故障:在一个完整的GPT分区磁盘上,丢失了GPT主分区表,或备份分区表 ...
- C语言Linix服务器网络爬虫项目(二)项目设计和通过一个http请求抓取网页的简单实现
我们通过上一篇了解了爬虫具体要实现的工作之后,我们分析得出的网络爬虫的基本工作流程如下: 1.首先选取一部分精心挑选的种子URL: 2.将这些URL放入待抓取URL队列: 3.从待抓取URL队列中取出 ...
- 基于 Java NIO 实现简单的 HTTP 服务器
1.简介 本文是上一篇文章实践篇,在上一篇文章中,我分析了选择器 Selector 的原理.本篇文章,我们来说说 Selector 的应用,如标题所示,这里我基于 Java NIO 实现了一个简单的 ...
- Python内置函数(1)——abs
英文文档: abs(x) Return the absolute value of a number. The argument may be an integer or a floating poi ...
- GIT入门笔记(13)- GUI GIT
- 【52ABP实战教程】0.1-- Devops如何用VSTS持续集成到Github仓库!
工欲善其事,必先利其器.在开始正式的教程之前我们先来聊聊准备工作. 管理工具会VSTS. 代码管理会用GITHUB. 服务器会用Azure. 所有的东西都是利用现有服务.不会说自己从虚拟机开始玩.我们 ...
- 启动Eclipse时An internal error occurred during: "Initializing Java Tooling".错误
解决方法一 重置窗口布局: windows > perspective > reset perspective 解决方法二: 如果上述方法不好使,采用下面的这种方法: 删除workspac ...
- java 中String类的常用方法总结,带你玩转String类。
String类: String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象.String类对象创建后不能修改,StringBuffer & St ...
- python github
git 1. 版本控制 是否依稀记得你的毕业论文? 1 2 3 4 5 6 7 8 9 10 11 毕业论文_初稿.doc 毕业论文_修改1.doc 毕业论文_修改2.doc 毕业论文_修改3.doc ...