Gym-101158J Cover the Polygon with Your Disk 计算几何 求动圆与多边形最大面积交
题意:给出小于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 计算几何 求动圆与多边形最大面积交的更多相关文章
- Gym101158 J 三分 or 模拟退火 Cover the Polygon with Your Disk
目录 Gym101158 J: 求圆与给定凸多边形最大面积交 模拟退火 三分套三分 模拟退火套路 @ Gym101158 J: 求圆与给定凸多边形最大面积交 传送门:点我点我 求 $10 $ 个点组成 ...
- 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 ...
- Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
Problem A. AerodynamicsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/co ...
- Gym - 100851A Adjustment Office(O(1)求行列和)
Adjustment Office Gym - 100851A 2 3 4 3 4 5 4 5 6 n<=10^6,q&l ...
- Gym - 101208J 2013 ACM-ICPC World Finals J.Pollution Solution 圆与多边形面积交
题面 题意:给你一个半圆,和另一个多边形(可凹可凸),求面积交 题解:直接上板子,因为其实这个多边形不会穿过这个半圆,所以他和圆的交也就是和半圆的交 打的时候队友说凹的不行,不是板题,后面想想,圆与多 ...
- HDU 5130 Signal Interference(计算几何 + 模板)
HDU 5130 Signal Interference(计算几何 + 模板) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5130 Descripti ...
- HDU - 3642 Get The Treasury(线段树求体积交)
https://cn.vjudge.net/problem/HDU-3642 题意 求立方体相交至少3次的体积. 分析 三维的呢..首先解决至少覆盖三次的问题.则用三个标记,更新时的细节要注意. 注意 ...
- 2018.07.03 POJ 1279Art Gallery(半平面交)
Art Gallery Time Limit: 1000MS Memory Limit: 10000K Description The art galleries of the new and ver ...
- Gym - 101982F Rectangles (扫描线+线段树)
链接:http://codeforces.com/gym/101982/attachments 思路: 问被覆盖次数为奇数次的矩阵的面积并 扫描线求矩阵面积并我们是上界赋为-1,下界赋为1,因为要求覆 ...
随机推荐
- href标签中target的几个属性值
没有指定<a>的target属性值时,默认是"_blank,可以参考以下代码的设置来控制<a href="#" target="_blank& ...
- dubbo之启动时检查
启动时检查 Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认 check="true".所以可以通过 ...
- Christopher G. Atkeson 简介
有一个事实:双足机器人的稳定性问题单靠算法是搞不定的!!! 在2015 DARPA 机器人挑战赛中,许多参赛团队的机器人使用了Atlas,他们通过安装他们自己的软件并修改来让机器人保持平衡.来自WPI ...
- 【sqli-labs】 less12 POST - Error Based - Double quotes- String-with twist (基于错误的双引号POST型字符型变形的注入)
加个双引号 通过报错信息猜测SQL语句 , 将括号闭合掉,通过注释后面的条件登录
- js 立即调用函数
function makeCounter() { //不能立即执行 // 只能在makeCounter内部访问i var i = 0; return function () { console.log ...
- Python统计字符串中出现次数最多的人名
人名最多数统计题目摘自https://python123.io 描述编程模板中给出了一个字符串,其中包含了含有重复的人名,请直接输出出现最多的人名. ...
- vim/vi编辑器挂到后台ctrl + z
vim/vi编辑器通过CTRL+z将文件挂在到后台后,如果要再次进入,需通过jobs查看文件的序号,然后通过fg 序号进入文件进行编辑 (BaiduPictureToWord) [master@ins ...
- QBXT Day2
遭遇[问题描述]你是能看到第一题的 friends呢.—— hjaN座楼房,立于城中 .第i座楼,高度 hi.你需要一开始选择座楼,开始跳楼. 在第 i座楼准备跳需要 ci的花费. 每次可以跳到任何一 ...
- constraint、index、view(day04)
回顾: 1.sql99中的表连接 select 字段列表 from 左表 {[inner]|{left|right|full} [outer]} join 右表 on 关联条件; 集合操作 union ...
- [jzoj 5775]【NOIP2008模拟】农夫约的假期 (前缀和+递推)
传送门 Description 在某国有一个叫农夫约的人,他养了很多羊,其中有两头名叫mm和hh,他们的歌声十分好听,被当地人称为"魔音"······ 农夫约也有自己的假期呀!他要 ...