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,因为要求覆 ...
随机推荐
- JQuery特效之心形图片墙
效果如图: 代码如下: <!doctype html> <html lang="en"> <head> <meta charset=&qu ...
- mac 上执行 rm -rf /
# 很可怕的指令,清空磁盘所有资料,千万不要用 sudo 尝试,吓的小心肝差掉跳出来 rm -rf / 无聊,想执行rm -rf /会怎样,想起没加sudo时对~/download执行提示权限不足,被 ...
- Apache_安装
1.下载安装包 网址:https://www.apachelounge.com/download/,下载你需要的安装包 2.解压文件到指定安装目录 3.修改配置文件 使用文本编辑器打开配置文件 con ...
- OAuth网络协议
一.应用场景 为了理解OAuth的适用场合,让我举一个假设的例子. 有一个"云冲印"的网站,可以将用户储存在Google的照片,冲印出来.用户为了使用该服务,必须让"云冲 ...
- 理解Linux CPU负载和 CPU使用率
CPU负载和 CPU使用率 这两个从一定程度上都可以反映一台机器的繁忙程度. cpu使用率反映的是当前cpu的繁忙程度,忽高忽低的原因在于占用cpu处理时间的进程可能处于io等待状态但却还未释放进入w ...
- php进程daemon化的正确做法
[原文地址:https://blog.ti-node.com/blog...] daemon 音标 : ['di:mən] , 中文含义为守护神或精灵的意思 . 其实它还有个意思 : 守护进程 . 守 ...
- FusionCharts,双折线图和双柱状图
一个电商项目中,用到了"双柱状图",对比 当前库存和累计库存. 网上找了好几个贴子,才找到具体用法. 代码整理下,以备不时之需. 效果图-双折线图 效果图-双柱状图 <%@ ...
- 如鹏网JAVA培训笔记2(晓伟整理)
输入输出: 我们使用System.out.println(“abc”);作用:向控制台输入东西. Scaner sc=new Scanner(System.in)://从输入流中去读取 int age ...
- [bzoj1316]树上的询问_点分治
树上的询问 bzoj-1316 题目大意:一棵n个点的带权有根树,有p个询问,每次询问树中是否存在一条长度为Len的路径,如果是,输出Yes否输出No. 注释:$1\le n\le 10^4$,$1\ ...
- 洛谷 P2534 [AHOI2012]铁盘整理
P2534 [AHOI2012]铁盘整理 题目描述 输入输出格式 输入格式: 共两行.第一行为铁盘个数N(1<=N<=50),第二行为N个不同的正整数,分别为从上到下的铁盘的半径R.(1& ...