题面

题意:给出小于10个点形成的凸多边形 和一个半径为r 可以移动的圆 求圆心在何处的面积交最大,面积为多少

题解:三分套三分求出圆心位置,再用圆与多边形面积求交

 #include<bits/stdc++.h>
#define inf 1000000000000
#define M 100009
#define eps 1e-12
#define PI acos(-1.0)
using namespace std;
struct node
{
double x,y;
node(){}
node(double xx,double yy)
{
x=xx;
y=yy;
}
node operator -(node s)
{
return node(x-s.x,y-s.y);
}
node operator +(node s)
{
return node(x+s.x,y+s.y);
}
double operator *(node s)
{
return x*s.x+y*s.y;
}
double operator ^(node s)
{
return x*s.y-y*s.x;
}
}p[M],a[M];
double max(double a,double b)
{
return a>b?a:b;
}
double min(double a,double b)
{
return a<b?a:b;
}
double len(node a)
{
return sqrt(a*a);
}
double dis(node a,node b)//两点之间的距离
{
return len(b-a);
}
double cross(node a,node b,node c)//叉乘
{
return (b-a)^(c-a);
}
double dot(node a,node b,node c)//点乘
{
return (b-a)*(c-a);
}
int judge(node a,node b,node c)//判断c是否在ab线段上(前提是c在直线ab上)
{
if(c.x>=min(a.x,b.x)
&&c.x<=max(a.x,b.x)
&&c.y>=min(a.y,b.y)
&&c.y<=max(a.y,b.y))
return ;
return ;
}
double area(node b,node c,double r)
{
node a(0.0,0.0);
if (dis(b,c)<eps) return 0.0;
double h=fabs(cross(a,b,c))/dis(b,c);
if(dis(a,b)>r-eps&&dis(a,c)>r-eps)//两个端点都在圆的外面则分为两种情况
{
double angle=acos(dot(a,b,c)/dis(a,b)/dis(a,c));
if(h>r-eps)
{
return 0.5*r*r*angle;
}
else if(dot(b,a,c)>&&dot(c,a,b)>)
{
double angle1=*acos(h/r);
return 0.5*r*r*fabs(angle-angle1)+0.5*r*r*sin(angle1);
}
else
{
return 0.5*r*r*angle;
}
}
else if(dis(a,b)<r+eps&&dis(a,c)<r+eps)//两个端点都在圆内的情况
{
return 0.5*fabs(cross(a,b,c));
}
else//一个端点在圆上一个端点在圆内的情况
{
if(dis(a,b)>dis(a,c))//默认b在圆内
{
swap(b,c);
}
if(fabs(dis(a,b))<eps)//ab距离为0直接返回0
{
return 0.0;
}
if(dot(b,a,c)<eps)
{
double angle1=acos(h/dis(a,b));
double angle2=acos(h/r)-angle1;
double angle3=acos(h/dis(a,c))-acos(h/r);
return 0.5*dis(a,b)*r*sin(angle2)+0.5*r*r*angle3; }
else
{
double angle1=acos(h/dis(a,b));
double angle2=acos(h/r);
double angle3=acos(h/dis(a,c))-angle2;
return 0.5*r*dis(a,b)*sin(angle1+angle2)+0.5*r*r*angle3;
}
}
}
int n;
double x,y,h,x1,yy,R;
double gets(node O)//求圆与多边形面积并
{
for (int i=;i<=n+;i++) p[i]=a[i];
for(int i=;i<=n+;i++) p[i]=p[i]-O;
O=node(,);
double sum=;
for(int i=;i<=n;i++)
{
int j=i+;
double s=area(p[i],p[j],R);
if(cross(O,p[i],p[j])>) sum+=s; else sum-=s;
}
return fabs(sum);
}
int dcmp(double x)
{
if(x > eps) return ;
return x < -eps ? - : ;
}
double calc(double x)
{
double l=,r=-,m1,m2,f1=,f2=;
for (int i=;i<=n;i++)
{
if (dcmp((a[i].x-x) * (a[i+].x-x))<=)
{
node tmp;
tmp.x=a[i].x+(a[i+].x-a[i].x)/(a[i+].x-a[i].x)*(x-a[i].x);
tmp.y=a[i].y+(a[i+].y-a[i].y)/(a[i+].x-a[i].x)*(x-a[i].x);
l=min(l,tmp.y);
r=max(r,tmp.y);
}
}
while (l+eps<r)
{
m1=(l+l+r)/3.0;
node bom=node(x,m1);
f1=gets(bom);
m2=(l+r+r)/3.0;
bom=node(x,m2);
f2=gets(bom);
if (f1>f2) r=m2;else l=m1;
}
return f1;
}
int main()
{
scanf("%d%lf",&n,&R);
double l=,r=-,m1,m2,f1,f2;
for(int i=;i<=n;i++)
{
scanf("%lf%lf",&a[i].x,&a[i].y);
l=min(l,a[i].x);
r=max(r,a[i].x);
}
a[n+]=a[];
while (l+eps<r)
{
m1=(l+l+r)/3.0;f1=calc(m1);
m2=(l+r+r)/3.0;f2=calc(m2);
if (f1>f2) r=m2;else l=m1;
}
printf("%.6lf\n",f1);
return ;
}

Gym-101158J Cover the Polygon with Your Disk 计算几何 求动圆与多边形最大面积交的更多相关文章

  1. Gym101158 J 三分 or 模拟退火 Cover the Polygon with Your Disk

    目录 Gym101158 J: 求圆与给定凸多边形最大面积交 模拟退火 三分套三分 模拟退火套路 @ Gym101158 J: 求圆与给定凸多边形最大面积交 传送门:点我点我 求 $10 $ 个点组成 ...

  2. Gym 100952J&&2015 HIAST Collegiate Programming Contest J. Polygons Intersection【计算几何求解两个凸多边形的相交面积板子题】

    J. Polygons Intersection time limit per test:2 seconds memory limit per test:64 megabytes input:stan ...

  3. Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积

    Problem A. AerodynamicsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/co ...

  4. Gym - 100851A Adjustment Office(O(1)求行列和)

    Adjustment Office Gym - 100851A 2       3       4 3       4       5 4       5       6 n<=10^6,q&l ...

  5. Gym - 101208J 2013 ACM-ICPC World Finals J.Pollution Solution 圆与多边形面积交

    题面 题意:给你一个半圆,和另一个多边形(可凹可凸),求面积交 题解:直接上板子,因为其实这个多边形不会穿过这个半圆,所以他和圆的交也就是和半圆的交 打的时候队友说凹的不行,不是板题,后面想想,圆与多 ...

  6. HDU 5130 Signal Interference(计算几何 + 模板)

    HDU 5130 Signal Interference(计算几何 + 模板) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5130 Descripti ...

  7. HDU - 3642 Get The Treasury(线段树求体积交)

    https://cn.vjudge.net/problem/HDU-3642 题意 求立方体相交至少3次的体积. 分析 三维的呢..首先解决至少覆盖三次的问题.则用三个标记,更新时的细节要注意. 注意 ...

  8. 2018.07.03 POJ 1279Art Gallery(半平面交)

    Art Gallery Time Limit: 1000MS Memory Limit: 10000K Description The art galleries of the new and ver ...

  9. Gym - 101982F Rectangles (扫描线+线段树)

    链接:http://codeforces.com/gym/101982/attachments 思路: 问被覆盖次数为奇数次的矩阵的面积并 扫描线求矩阵面积并我们是上界赋为-1,下界赋为1,因为要求覆 ...

随机推荐

  1. 01--Java IO基础

    一.java.io包概览 Java IO包主要可以分为如下4类: 基于字节操作的I/O接口:InputStream和OutputStream. 基于字符操作的I/O接口:Writer和Reader 基 ...

  2. Excel 批量出来数据

    try { string sheetname = TextBox1.Text.Trim(); HttpPostedFile upLoadPostFile = FileUpload1.PostedFil ...

  3. List 练习

    (List)已知有一个Worker 类如下: public class Worker { private int age; private String name; private double sa ...

  4. 在 ef 中执行 DbContext.Table.AddRange(Enitites).ToList() 会发生什么

    在 ef 中执行 DbContext.Table.AddRange(Enitites).ToList() 会发生什么 昨天和朋友摸鱼,无意之间聊到了执行 DbContext.Table.AddRang ...

  5. 解析MYsql写的表达式

    今天遇到个问题,Sql中直接写的是复杂表达式,如何解析呢? round(((0.00579049505+0.00006600324*JING_JIE^2*SHU_GAO-0.00000046921*J ...

  6. jboss的下载安装、环境变量配置以及部署

    1. 下载安装 http://jbossas.jboss.org/downloads/   jdk为1.7 我下载的是:JBoss AS7.1.1.Final 2. 解压安装包  D:\program ...

  7. bzoj4320 homework 题解

    题面链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4320 令M=sqrt(mx),把询问的Y按M 分成两种不同的处理方式. 1.对于> ...

  8. linux vi面板如何复制一行

    linux vi面板如何复制一行 1)把光标移动到要复制的行上 2)按yy 3)把光标移动到要复制的位置 4)按p

  9. tornado服务器运行django应用

    在jumpserver项目中看到的 def main(): from django.core.wsgi import get_wsgi_application import tornado.wsgi ...

  10. __call__ 和 __str__ 魔术方法

    魔术方法,在python中,是通过触发的形式调用,之所以称为魔术方法,是因为不需要特地的打印或调用它,在某些特定的时候,他会自己调用,所谓的特定的时候,也是我们自己所输入的代码操作的,不是莫名其妙的触 ...