链接:https://www.nowcoder.com/acm/contest/141/J
来源:牛客网

Eddy has graduated from college. Currently, he is finding his future job and a place to live. Since Eddy is currently living in Tien-long country, he wants to choose a place inside Tien-long country to live. Surprisingly, Tien-long country can be represented as a simple polygon on 2D-plane. More surprisingly, Eddy can choose any place inside Tien-long country to live. The most important thing Eddy concerns is the distance from his place to the working place. He wants to live neither too close nor too far to the working place. The more specific definition of "close" and "far" is related to working place.

Eddy has M choices to work in the future. For each working place, it can be represented as a point on 2D-plane. And, for each working place, Eddy has two magic parameters P and Q such that if Eddy is going to work in this place, he will choose a place to live which is closer to the working place than portion of all possible living place choices.

Now, Eddy is wondering that for each working place, how far will he lives to the working place. Since Eddy is now busy on deciding where to work on, you come to help him calculate the answers.

For example, if the coordinates of points of Tien-long country is (0,0), (2,0), (2, 2), (0, 2) in counter-clockwise order. And, one possible working place is at (1,1) and P=1, Q=2. Then, Eddy should choose a place to live which is closer to (1, 1) than half of the choices. The distance from the place Eddy will live to the working place will be about 0.7978845608.

输入描述:

The first line contains one positive integer N indicating the number of points of the polygon representing Tien-long country.
Each of following N lines contains two space-separated integer (x

i

, y

i

) indicating the coordinate of i-th points. These points is given in clockwise or counter-clockwise order and form the polygon.
Following line contains one positive integer M indicating the number of possible working place Eddy can choose from.
Each of following M lines contains four space-separated integer x

j

, y

j

, P, Q, where (x

j

, y

j

) indicating the j-th working place is at (x

j

, y

j

) and magic parameters is P and Q.
3 ≤ N ≤ 200
1 ≤ M ≤ 200
1 ≤ P < Q ≤ 200
|x

i

|, |y

i

|, |x

j

|, |y

j

| ≤ 103
It's guaranteed that the given points form a simple polygon.

输出描述:

Output M lines. For i-th line, output one number indicating the distance from the place Eddy will live to the i-th working place.

Absolutely or relatively error within 10-6
 will be considered correct.

输入例子:
4
0 0
2 0
2 2
0 2
1
1 1 1 2
输出例子:
0.797884560809

-->

示例1

输入

复制

4
0 0
2 0
2 2
0 2
1
1 1 1 2

输出

复制

0.797884560809
示例2

输入

复制

3
0 0
1 0
2 1
2
0 0 1 2
1 1 1 3

输出

复制

1.040111537176
0.868735603376
题意:给你一个多变形,再给你几个圆心点,问每个圆心点的半径为多少时,圆的面积为多边形面积的(1-p/q)

分析:一个多边形与圆相交的模板题,求圆心点半径的时候二分就行,限制二分次数保证精度

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib> using namespace std; const double eps = 1e-9;
const double PI = acos(-1.0); int dcmp(double x)
{
if( x > eps ) return 1;
return x < -eps ? -1 : 0;
} struct Point
{
double x,y;
Point()
{
x = y = 0;
}
Point(double a,double b)
{
x = a;
y = b;
}
inline void input()
{
scanf("%lf%lf",&x,&y);
}
inline Point operator-(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
inline Point operator+(const Point &b)const
{
return Point(x + b.x,y + b.y);
}
inline Point operator*(const double &b)const
{
return Point(x * b,y * b);
}
inline double dot(const Point &b)const
{
return x * b.x + y * b.y;
}
inline double cross(const Point &b,const Point &c)const
{
return (b.x - x) * (c.y - y) - (c.x - x) * (b.y - y);
}
inline double Dis(const Point &b)const
{
return sqrt((*this-b).dot(*this-b));
}
inline bool InLine(const Point &b,const Point &c)const //三点共线
{
return !dcmp(cross(b,c));
}
inline bool OnSeg(const Point &b,const Point &c)const //点在线段上,包括端点
{
return InLine(b,c) && (*this - c).dot(*this - b) < eps;
}
int operator^(const Point &b) const
{
return y*b.x-x*b.y;
}
}; inline double min(double a,double b)
{
return a < b ? a : b;
}
inline double max(double a,double b)
{
return a > b ? a : b;
}
inline double Sqr(double x)
{
return x * x;
}
inline double Sqr(const Point &p)
{
return p.dot(p);
} Point LineCross(const Point &a,const Point &b,const Point &c,const Point &d)
{
double u = a.cross(b,c), v = b.cross(a,d);
return Point((c.x * v + d.x * u) / (u + v), (c.y * v + d.y * u) / (u + v));
} double LineCrossCircle(const Point &a,const Point &b,const Point &r,
double R,Point &p1,Point & p2)
{
Point fp = LineCross(r, Point(r.x+a.y-b.y, r.y+b.x-a.x), a, b);
double rtol = r.Dis(fp);
double rtos = fp.OnSeg(a, b) ? rtol : min(r.Dis(a), r.Dis(b));
double atob = a.Dis(b);
double fptoe = sqrt(R * R - rtol * rtol) / atob;
if( rtos > R - eps ) return rtos;
p1 = fp + (a - b) * fptoe;
p2 = fp + (b - a) * fptoe;
return rtos;
} double SectorArea(const Point &r,const Point &a,const Point &b,double R) //不大于180度扇形面积,r->a->b逆时针
{
double A2 = Sqr(r - a), B2 = Sqr(r - b), C2 = Sqr(a - b);
return R * R * acos( (A2 + B2 - C2) * 0.5 / sqrt(A2) / sqrt(B2)) * 0.5;
} double TACIA(const Point &r,const Point &a,const Point &b,double R)
{
double adis = r.Dis(a), bdis = r.Dis(b);
if( adis < R + eps && bdis < R + eps )
return r.cross(a, b) * 0.5;
Point ta, tb;
if( r.InLine(a,b) ) return 0.0;
double rtos = LineCrossCircle(a, b, r, R, ta, tb);
if( rtos > R - eps )
return SectorArea(r, a, b, R);
if( adis < R + eps )
return r.cross(a, tb) * 0.5 + SectorArea(r, tb, b, R);
if( bdis < R + eps )
return r.cross(ta, b) * 0.5 + SectorArea(r, a, ta, R);
return r.cross(ta, tb) * 0.5 + SectorArea(r, tb, b, R) + SectorArea(r, a, ta, R);
} const int MAXN = 505;
Point p[MAXN]; double SPICA(int n,Point r,double R)
{
int i;
double ret = 0, if_clock_t;
for( i = 0 ; i < n ; ++i )
{
if_clock_t = dcmp(r.cross(p[i], p[(i + 1) % n]));
if( if_clock_t < 0 )
ret -= TACIA(r, p[(i + 1) % n], p[i], R);
else ret += TACIA(r, p[i], p[(i + 1) % n], R);
}
return fabs(ret);
} double ComputePolygonArea(int n)
{
double sum=0;
for(int i=1;i<=n-1;i++)
sum+=(p[i]^p[i-1]);
sum+=(p[0]^p[n-1]);
return fabs(sum/2);
} int main()
{
int n,m;
scanf("%d",&n);///多边形n个顶点
for(int i = 0 ; i < n ; ++i )///顶点坐标
p[i].input();
double polyArea = ComputePolygonArea(n);///计算多边形面积
scanf("%d",&m);
while(m--)
{ Point circle;
circle.input(); ///圆心坐标
int pp,qq;
scanf("%d%d",&pp,&qq);
double area = (1.0-(double)pp/qq)*polyArea; ///二分圆的半径
// printf("%f\n",area);
double l =0, r=1e18;
///固定二分次数
for(int i=1;i<300;i++){
double mid = (l+r)/2.0;
double insection = SPICA(n,circle,mid); ///圆与多边形交的面积
if(insection>area){
r = mid-eps;
}else{
l = mid;
}
}
printf("%.10lf\n",r);
}
return 0;
}

  

牛客网暑期ACM多校训练营(第三场) J Distance to Work 计算几何求圆与多边形相交面积模板的更多相关文章

  1. 牛客网暑期ACM多校训练营(第二场)J farm (二维树状数组)

    题目链接: https://www.nowcoder.com/acm/contest/140/J 思路: 都写在代码注释里了,非常好懂.. for_each函数可以去看一下,遍历起vector数组比较 ...

  2. 牛客网 暑期ACM多校训练营(第二场)A.run-动态规划 or 递推?

    牛客网暑期ACM多校训练营(第二场) 水博客. A.run 题意就是一个人一秒可以走1步或者跑K步,不能连续跑2秒,他从0开始移动,移动到[L,R]的某一点就可以结束.问一共有多少种移动的方式. 个人 ...

  3. 牛客网 暑期ACM多校训练营(第一场)A.Monotonic Matrix-矩阵转化为格子路径的非降路径计数,Lindström-Gessel-Viennot引理-组合数学

    牛客网暑期ACM多校训练营(第一场) A.Monotonic Matrix 这个题就是给你一个n*m的矩阵,往里面填{0,1,2}这三种数,要求是Ai,j⩽Ai+1,j,Ai,j⩽Ai,j+1 ,问你 ...

  4. 2018牛客网暑期ACM多校训练营(第二场)I- car ( 思维)

    2018牛客网暑期ACM多校训练营(第二场)I- car 链接:https://ac.nowcoder.com/acm/contest/140/I来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 ...

  5. 牛客网暑期ACM多校训练营(第一场) - J Different Integers(线段数组or莫队)

    链接:https://www.nowcoder.com/acm/contest/139/J来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048 ...

  6. 牛客网暑期ACM多校训练营(第九场) A题 FWT

    链接:https://www.nowcoder.com/acm/contest/147/A来源:牛客网 Niuniu has recently learned how to use Gaussian ...

  7. 牛客网暑期ACM多校训练营(第九场)D

    链接:https://www.nowcoder.com/acm/contest/147/D来源:牛客网 Niuniu likes traveling. Now he will travel on a ...

  8. 牛客网暑期ACM多校训练营(第二场)B discount

    链接:https://www.nowcoder.com/acm/contest/140/B来源:牛客网 题目描述 White Rabbit wants to buy some drinks from ...

  9. 2018牛客网暑期ACM多校训练营(第一场)D图同构,J

    链接:https://www.nowcoder.com/acm/contest/139/D来源:牛客网 同构图:假设G=(V,E)和G1=(V1,E1)是两个图,如果存在一个双射m:V→V1,使得对所 ...

随机推荐

  1. docker的基本安装和命令详解

    docker的安装 yum install docker-io docker的启动 /bin/systemctl start docker.service docker查找镜像 docker sear ...

  2. Laravel 命令行工具之多线程同步大批量数据 DB连接混乱 解决方案

    记一次大批量数据的多进程同步 背景:因为公司的用户标识不完整,所以需要从集团同步一次用户标记数据,用户数据来源是微信,数量级为一百五十万,集团用户数量级为六百万 方案确定下来是集团开了一个查询接口,访 ...

  3. 曹工杂谈:Linux服务器上,Spring Boot 原地修改 jar 包配置文件/替换class文件,免去重复上传的麻烦

    一.前言 相信很多同学有这样的需求,现在很多公司都有多地的研发中心,经常需要跨地区部署,比如,博主人在成都,但是服务器是北京的.一般城市间网络都不怎么好,上传一个几十兆的jar包那是真的慢,别说现在微 ...

  4. mysql是如何实现事务隔离以及MVCC详解

    提到事务,你肯定会想到ACID(Atomicity.Consistency.Isolation.Durability,即原子性.一致性.隔离性.持久性),我们就来说说其中I,也就是"隔离性& ...

  5. xpath beautiful pyquery三种解析库

    这两天看了一下python常用的三种解析库,写篇随笔,整理一下思路.太菜了,若有错误的地方,欢迎大家随时指正.......(conme on.......) 爬取网页数据一般会经过 获取信息-> ...

  6. 使用Junit测试一个 spring静态工厂实例化bean 的例子,所有代码都没有问题,但是出现java.lang.IllegalArgumentException异常

    使用Junit测试一个spring静态工厂实例化bean的例子,所有代码都没有问题,但是出现 java.lang.IllegalArgumentException 异常, 如下图所示: 开始以为是代码 ...

  7. 01-Spring Security框架学习

    目录 01-Spring Security框架学习 简介 Spring Security 是什么 Spring Security 解决那些问题 Spring Security 的优点 历史背景 Spr ...

  8. curl工具使用实例

    curl是一个命令行工具,其基于libcurl库,用于发送网络请求,获取并展示响应数据,下面来看curl的具体用法. 1.下载网页源码 curl命令直接接URL,用于下载指定URL的网页源码,并将其显 ...

  9. C语言之左移和右移运算符

    C语言中的左移和右移运算符移位后的结果老是忘记,最近在刷有关位操作的题目,正好整理下:   1. 左移运算符(<<) 左移运算符是用来将一个数的各二进制位左移若干位,移动的位数由右操作数指 ...

  10. UI 组件 | Button

    最近在与其他自学 Cocos Creator 的小伙伴们交流过程中,发现许多小伙伴对基础组件的应用并不是特别了解,自己在编写游戏的过程中也经常对某个属性或者方法的用法所困扰,而网上也没有比较清晰的用法 ...