Gym - 101617F :Move Away (圆的交点)

pro:给定N个圆,求离原点最远的点,满足它在N个圆里。输出这个距离。N<50;

sol:关键点一定是圆与圆的交点。 圆与 圆心到原点的直线 的交点。 然后去验证这些关键点是否在N个圆内。 实际操作的时候需要考虑一些条件:

1,求圆的交点的时候,先判断是否内含或者相离。

2,求直线与圆的交点的时候,先判断是否圆心就在原点处。

3,有可能不存在相交的圆。

如何求圆与圆的交点:

用atan2求出t,余弦定理求出a,即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=10010;
const double eps=1e-8;
const double pi=acos(-1.0);
struct point{
    double x,y;
    point(){}
    point(double xx,double yy):x(xx),y(yy){}
};
struct Circle{
    point c;
    double r;
};
point operator +(point a,point b){ return point(a.x+b.x,a.y+b.y);}
point operator -(point a,point b){ return point(a.x-b.x,a.y-b.y);}
point operator *(point a,double p){return point(a.x*p,a.y*p);}
point operator /(point a,double p){ return point(a.x/p,a.y/p);}
double dot(point a,point b){ return a.x*b.x+a.y*b.y;}
double det(point a,point b){ return a.x*b.y-a.y*b.x;}
Circle C[maxn]; point P[maxn]; int tot,N; double ans1,ans2;
void CirintersectCir(Circle A,Circle B)
{
    point L=B.c-A.c;
    double dis=sqrt(dot(L,L));
    if(dis>A.r+B.r||fabs(A.r-B.r)>=dis+eps) return ;
    double angle1=atan2(L.y,L.x);
    double angle2=acos((A.r*A.r+dis*dis-B.r*B.r)/(2*A.r*dis));
    P[++tot]=point(A.c.x+A.r*cos(angle1+angle2),A.c.y+A.r*sin(angle1+angle2));
    P[++tot]=point(A.c.x+A.r*cos(angle1-angle2),A.c.y+A.r*sin(angle1-angle2));
}
void OtoCir(Circle A)
{
    double dis=sqrt(dot(A.c,A.c));
    P[++tot]=A.c+A.c*A.r/dis;
}
int fcy=0; double R;
bool check(point p)
{
    rep(i,1,N)
      if(sqrt(dot(p-C[i].c,p-C[i].c))>C[i].r+eps) return false;
    if(fcy&&sqrt(dot(p,p))>R+eps) return false;
    return true;
}
int main()
{
    scanf("%d",&N);
    rep(i,1,N){
         scanf("%lf%lf%lf",&C[i].c.x,&C[i].c.y,&C[i].r);
         if(C[i].c.x==0.0&&C[i].c.y==0.0) {
            if(fcy==0) fcy=1,R=C[i].r;
            else R=min(R,C[i].r);
            if(ans1==0) ans1=C[i].r;
            else ans2=min(ans2,C[i].r);
            i--; N--;
         }
    }
    if(fcy){
        Circle T; T.r=R; T.c.x=T.c.y=0;
        rep(i,1,N){
            P[++tot]=C[i].c/sqrt(dot(C[i].c,C[i].c))*R;
            CirintersectCir(T,C[i]);
        }
    }
    rep(i,1,N)
     rep(j,i+1,N)
      CirintersectCir(C[i],C[j]);
    rep(i,1,N) OtoCir(C[i]);
    rep(i,1,tot)
      if(check(P[i]))
        ans2=max(ans2,sqrt(dot(P[i],P[i])));
    if(ans2!=0.0) printf("%.3lf\n",ans2);
    else printf("%.3lf\n",ans1);
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/10700781.html

时间: 2024-07-31 15:46:35

Gym - 101617F :Move Away (圆的交点)的相关文章

第十二周项目4-3:点,圆的关系-输出线和圆的交点

问题及代码: /* *Copyright (c)2015,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:project.cpp *作 者:陈文青 *完成日期:2015年5月31日 *版 本 号:v1.0 * *问题描述: (6)与圆心相连的直线:给定一点p,其与圆心相连成的直线,会和圆有两个交点,如图.在上面定义的Point(点)类和Circle(圆)类基础上, 设计一种方案,输出这两点的坐标. *程序输入: *程序输出: */ #include <ios

如何用几何画板构造直线与圆的交点

在学习数学几何时,经常会遇到圆与直线的关系问题.今天小编就来教大家如何用几何画板构造直线与圆的交点,从而能直观的表现出圆与直线的关系. 具体的操作步骤如下: 1.打开几何画板软件,执行“绘图”—“绘制新函数”命令,在弹出的对话框中依次单击“2”.“x”,做出函数解析式f(x)=2x,如下图所示,单击“确定”按钮,做出函数图像. 2.利用“圆工具”绘制一个圆,同时选中圆和直线,执行“构造”—“交点”命令,构造直线和圆的交点. 3.单击“文本工具”,将交点的标签设为A.B,如下图所示.拖动圆改变位置

计算扇形与圆的交点

效果图: 算法: 基本思路是检测圆和圆的交点,检测扇形边和圆的交点,其中圆和圆的交点还要判断点是否在扇形的角度内部.判断方法参考: http://stackoverflow.com/questions/13652518/efficiently-find-points-inside-a-circle-sector 交点判断方法可以看之前的博客 internal class MathEx { /// <summary> /// 浮点类型的精度要求 /// </summary> publ

【计算几何】如何计算两个圆的交点坐标

How to calculate two coordinates of the intersection points of two circles? 题目: 给定两个圆的的方程 (x-x1)^2+(y-y1)^2=r1^2, (x-x2)^2+(y-y2)^2=r2^2 求解两个圆的交点坐标. 这种知识是高中的知识了,如果直接联立,由于计算特别暴力所以很难得到正确结果. 事实上,造成这种计算问题的结果是因为消去一个变量后,剩下变量的系数太过复杂. 我们通过更改坐标系的方法来使得另外一个系数变得

HDU 5572--An Easy Physics Problem(射线和圆的交点)

An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 3845    Accepted Submission(s): 768 Problem Description On an infinite smooth table, there's a big round fixed cylinder an

简单几何(直线与圆的交点) ZOJ Collision 3728

题目传送门 题意:有两个一大一小的同心圆,圆心在原点,大圆外有一小圆,其圆心有一个速度(vx, vy),如果碰到了小圆会反弹,问该圆在大圆内运动的时间 分析:将圆外的小圆看成一个点,判断该直线与同心圆的交点,根据交点个数计算时间.用到了直线的定义,圆的定义,直线与圆交点的个数. /************************************************ * Author :Running_Time * Created Time :2015/10/24 星期六 16:14:

【TOJ 5276】圆内交点

描述 现在有一个很大的圆,圆周上有N个互不重合的点,让这N个点两两连线,问连线有多少条,这些连线在圆的内部有多少个交点. 输入 多组输入,每行输入一个数字表示N(1 ≤ N ≤ 100); 输出 输出两个数字,第一个数字表示连线的条数,第二个数字表示园内交点的个数. 样例输入 24 样例输出 1 06 1 #include<bits/stdc++.h> double lncom(int n,int m) //在c语言中,log函数也就是我们通常所说的ln函数,即以e为底的对数函数 { doub

Gym 100342F Move to Front

用树状数组动态和查询修改排名. 树状数组可以很方便地查询前缀和,那么可以利用这一特点,记录一个点在树状数组里最后一次出现的位置, 查询出这个位置,就可以知道这个点的排名了.更改这个点的排名的时候只要把原来位置修改成0,然后在新的位置加上1就行了. 把询问离线,数据范围比较大,先用快排+去重离散(用map也可,就是慢了一点), 很久以前看的了,今天第一次实现 #include<bits/stdc++.h> using namespace std; const int maxn = 1e5+5,

2D空间中求两圆的交点

出处:https://stackoverflow.com/questions/19916880/sphere-sphere-intersection-c-3d-coordinates-of-collision-points 修改(加入包含和不相交情况的判断): using System.Collections; using System.Collections.Generic; using UnityEngine; public class CircleIntersect : MonoBehav