链接: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.

输入描述:

  1. 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 (xi,yi)
  1. indicating the coordinate of i-th points. These points is given in clockwise or counter-clockwise order and form the polygon.
  1. 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 xj,yj,P,Q, where (xj,yj) indicating the j-th working place is at (xj,yj) and
  1. magic parameters is P and Q.
    3<=N<=200
    1<=M<=200
    1<=P<Q<=200
    |xi||yi||xj||yj|<=1000
  1. It's guaranteed that the given points form a simple polygon.

输出描述:

  1. 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.
  2.  
  3. Absolutely or relatively error within 10^-6 will be considered correct.

输入例子:
  1. 4
  2. 0 0
  3. 2 0
  4. 2 2
  5. 0 2
  6. 1
  7. 1 1 1 2
输出例子:
  1. 0.797884560809

-->

示例1

输入

  1. 4
  2. 0 0
  3. 2 0
  4. 2 2
  5. 0 2
  6. 1
  7. 1 1 1 2

输出

  1. 0.797884560809
示例2

输入

  1. 3
  2. 0 0
  3. 1 0
  4. 2 1
  5. 2
  6. 0 0 1 2
  7. 1 1 1 3

输出

  1. 1.040111537176
  2. 0.868735603376

题意  一个国家由n个点组成  m次询问 每次给出一个工作地点(xj,yj)  从国家里选取居住地点 要满足 选取的点比国家内Q/P的点离工作地点更近  问居住点到工作地点的距离

解析  我们可以二分答案mid 然后判断以(xj,yj)为圆心mid为半径的圆 与 国家相交的面积 与 国家面积的比值 二分下去。

AC代码   偷得模板 。。。。

  1. #include <bits/stdc++.h>
  2. #define LL long long
  3. #define PI 3.1415926535897932384626
  4. #define maxn 1000
  5. #define EXIT exit(0);
  6. #define DEBUG puts("Here is a BUG");
  7. #define CLEAR(name, init) memset(name, init, sizeof(name))
  8. const double eps = 1e-;
  9. const int MAXN = (int)1e9 + ;
  10. using namespace std;
  11. #define Vector Point
  12. int dcmp(double x) { return fabs(x) < eps ? : (x < ? - : ); }
  13. struct Point {
  14. double x, y;
  15.  
  16. Point(const Point& rhs): x(rhs.x), y(rhs.y) { } //拷贝构造函数
  17. Point(double x = 0.0, double y = 0.0): x(x), y(y) { } //构造函数
  18.  
  19. friend istream& operator >> (istream& in, Point& P) { return in >> P.x >> P.y; }
  20. friend ostream& operator << (ostream& out, const Point& P) { return out << P.x << ' ' << P.y; }
  21.  
  22. friend Vector operator + (const Vector& A, const Vector& B) { return Vector(A.x+B.x, A.y+B.y); }
  23. friend Vector operator - (const Point& A, const Point& B) { return Vector(A.x-B.x, A.y-B.y); }
  24. friend Vector operator * (const Vector& A, const double& p) { return Vector(A.x*p, A.y*p); }
  25. friend Vector operator / (const Vector& A, const double& p) { return Vector(A.x/p, A.y/p); }
  26. friend bool operator == (const Point& A, const Point& B) { return dcmp(A.x-B.x) == && dcmp(A.y-B.y) == ; }
  27. friend bool operator < (const Point& A, const Point& B) { return A.x < B.x || (A.x == B.x && A.y < B.y); }
  28.  
  29. void in(void) { scanf("%lf%lf", &x, &y); }
  30. void out(void) { printf("%lf %lf", x, y); }
  31. };
  32.  
  33. template <class T> T sqr(T x) { return x * x;}
  34. double Dot(const Vector& A, const Vector& B) { return A.x*B.x + A.y*B.y; } //点积
  35. double Length(const Vector& A){ return sqrt(Dot(A, A)); }
  36. double Angle(const Vector& A, const Vector& B) { return acos(Dot(A, B)/Length(A)/Length(B)); } //向量夹角
  37. double Cross(const Vector& A, const Vector& B) { return A.x*B.y - A.y*B.x; } //叉积
  38. double Area(const Point& A, const Point& B, const Point& C) { return fabs(Cross(B-A, C-A)); }
  39. Vector normal(Vector x) { return Point(-x.y, x.x) / Length(x);}
  40. double angle(Vector x) { return atan2(x.y, x.x);}
  41.  
  42. Vector vecunit(Vector x){ return x / Length(x);} //单位向量
  43. struct Circle {
  44. Point c; //圆心
  45. double r; //半径
  46.  
  47. Circle() { }
  48. Circle(const Circle& rhs): c(rhs.c), r(rhs.r) { }
  49. Circle(const Point& c, const double& r): c(c), r(r) { }
  50.  
  51. Point point(double ang) const { return Point(c.x + cos(ang)*r, c.y + sin(ang)*r); } //圆心角所对应的点
  52. double area(void) const { return PI * r * r; }
  53. };
  54. struct Line {
  55. Point P; //直线上一点
  56. Vector dir; //方向向量(半平面交中该向量左侧表示相应的半平面)
  57. double ang; //极角,即从x正半轴旋转到向量dir所需要的角(弧度)
  58.  
  59. Line() { } //构造函数
  60. Line(const Line& L): P(L.P), dir(L.dir), ang(L.ang) { }
  61. Line(const Point& P, const Vector& dir): P(P), dir(dir) { ang = atan2(dir.y, dir.x); }
  62.  
  63. bool operator < (const Line& L) const { //极角排序
  64. return ang < L.ang;
  65. }
  66.  
  67. Point point(double t) { return P + dir*t; }
  68. };
  69.  
  70. bool InCircle(Point x, Circle c) { return dcmp(c.r*c.r - Length(c.c - x)*Length(c.c - x)) >= ;}
  71. Point GetIntersection(Line a, Line b) //线段交点
  72. {
  73. Vector u = a.P-b.P;
  74. double t = Cross(b.dir, u) / Cross(a.dir, b.dir);
  75. return a.P + a.dir*t;
  76. }
  77.  
  78. bool OnSegment(Point p, Point a1, Point a2)
  79. {
  80. return dcmp(Cross(a1-p, a2-p)) == && dcmp(Dot(a1-p, a2-p)) < ;
  81. }
  82. int getSegCircleIntersection(Line L, Circle C, Point* sol)
  83. {
  84. Vector nor = normal(L.dir);
  85. Line pl = Line(C.c, nor);
  86. Point ip = GetIntersection(pl, L);
  87. double dis = Length(ip - C.c);
  88. if (dcmp(dis - C.r) > ) return ;
  89. Point dxy = vecunit(L.dir) * sqrt(C.r*C.r - dis*dis);
  90. int ret = ;
  91. sol[ret] = ip + dxy;
  92. if (OnSegment(sol[ret], L.P, L.point())) ret++;
  93. sol[ret] = ip - dxy;
  94. if (OnSegment(sol[ret], L.P, L.point())) ret++;
  95. return ret;
  96. }
  97.  
  98. double SegCircleArea(Circle C, Point a, Point b) //线段切割圆
  99. {
  100. double a1 = angle(a - C.c);
  101. double a2 = angle(b - C.c);
  102. double da = fabs(a1 - a2);
  103. if (da > PI) da = PI * 2.0 - da;
  104. return dcmp(Cross(b - C.c, a - C.c)) * da * sqr(C.r) / 2.0;
  105. }
  106.  
  107. double PolyCiclrArea(Circle C, Point *p, int n)//多边形与圆相交面积
  108. {
  109. double ret = 0.0;
  110. Point sol[];
  111. p[n] = p[];
  112. for(int i=;i<n;i++)
  113. {
  114. double t1, t2;
  115. int cnt = getSegCircleIntersection(Line(p[i], p[i+]-p[i]), C, sol);
  116. if (cnt == )
  117. {
  118. if (!InCircle(p[i], C) || !InCircle(p[i+], C)) ret += SegCircleArea(C, p[i], p[i+]);
  119. else ret += Cross(p[i+] - C.c, p[i] - C.c) / 2.0;
  120. }
  121. if (cnt == )
  122. {
  123. if (InCircle(p[i], C) && !InCircle(p[i+], C)) ret += Cross(sol[] - C.c, p[i] - C.c) / 2.0, ret += SegCircleArea(C, sol[], p[i+]);
  124. else ret += SegCircleArea(C, p[i], sol[]), ret += Cross(p[i+] - C.c, sol[] - C.c) / 2.0;
  125. }
  126. if (cnt == )
  127. {
  128. if ((p[i] < p[i + ]) ^ (sol[] < sol[])) swap(sol[], sol[]);
  129. ret += SegCircleArea(C, p[i], sol[]);
  130. ret += Cross(sol[] - C.c, sol[] - C.c) / 2.0;
  131. ret += SegCircleArea(C, sol[], p[i+]);
  132. }
  133. }
  134. return fabs(ret);
  135. }
  136. double PolygonArea(Point *po, int n) {
  137. double area = 0.0;
  138. for(int i = ; i < n-; i++) {
  139. area += Cross(po[i]-po[], po[i+]-po[]);
  140. }
  141. return area * 0.5;
  142. }
  143. Point a[], b;
  144. double p, q;
  145. int main(){
  146. int n, m;
  147. scanf("%d", &n);
  148. for(int i=;i<n;i++) a[i].in();
  149. double ar = fabs(PolygonArea(a, n));
  150. scanf("%d", &m);
  151. for(int i=;i<m;i++){
  152. b.in();
  153. scanf("%lf%lf", &p, &q);
  154. double l = , r = , num = , mid, aa = -p/q;
  155. while(num--){
  156. mid = (l+r)/;
  157. Circle yuan(b, mid);
  158. if(PolyCiclrArea(yuan, a, n)/ar < aa) l = mid;
  159. else r = mid;
  160. }
  161. printf("%.10f\n", mid);
  162. }
  163. return ;
  164. }

牛客网暑期ACM多校训练营(第三场)J 多边形与圆相交的面积的更多相关文章

  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,使得对所 ...

  10. 牛客网暑期ACM多校训练营(第二场) I Car 思维

    链接:https://www.nowcoder.com/acm/contest/140/I来源:牛客网 White Cloud has a square of n*n from (1,1) to (n ...

随机推荐

  1. Android MVVM小结

    一.概念 关于MVC.MVP与MVVM的概念就不介绍了,总之一句话,MVVM概念出现比MVP早,MVP比MVC早,作为程序员就应该去学习最新的技术不是?详细的概念介绍移步这里吧,https://www ...

  2. (转)Spring+JDBC组合开发

    http://blog.csdn.net/yerenyuan_pku/article/details/52882435 搭建和配置Spring与JDBC整合的环境 使用Spring+JDBC集成步骤如 ...

  3. 目录下 shift 右键菜单 打开cmd 或者在 地址栏输入cmd 回车进入cmd

    目录下 shift 右键菜单 打开cmd 或者在 地址栏输入cmd 回车进入cmd

  4. Bug的定义和分类

    什么是BUG 使用人工或自动手段,来运行或测试某个系统的过程.其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别 BUG分类 完全没有实现的功能 基本实现了用户需要的功能,但是运行时 ...

  5. echart-柱状图

    目前在改别人遗留的bug,需求: 宽度 自适应的情况下 展示不友好:宽度太大 上下不居中 需求 要 上下 无论是否 有内容 都要居中展示 以0刻度为标准 宽度 设置 series: [ { name: ...

  6. C++虚析构函数的使用

    如果,你设计的程序里,释放对象实例的时候,有“使用某个基类的指针,来释放它指向的派生类的实例”这种用法出现的话,那么,这个基类的destructor就应该设计成virtual的. 如果,基类不是vir ...

  7. ideal取消按下两次shift弹出搜索框 修改idea,webstrom,phpstrom 快捷键double shift 弹出search everywhere

    因为经常需要在中英文之间切换,所以时常使用shift键,一不小心就把这个Searchwhere 对话框调出来了,很是麻烦. 因此痛定思痛, 我决定将这个按两下shift键就弹出搜索框的快捷键禁用了! ...

  8. image的resizeMode属性

    Image组件必须在样式中声明图片的宽和高.如果没有声明,则图片将不会被呈现在界面上.    我们一般将Image定义的宽和高乘以当前运行环境的像素密度称为Image的实际宽高. 当Image的实际宽 ...

  9. UVa-1586-分子量

    这是一道字符串的题目,我们直接对字符串进行解析,然后计算就可以了. 我是直接开了两个数组存入对应的值,没有进行判断,我们如果在if判断里面直接增加了i的值,最好先把对应的字符存起来,然后这样才不容易出 ...

  10. 测试linux服务器带宽

    测试准备 1. 计划考量参数 TCP上传数据带宽 TCP下载数据带宽 UDP上传带宽 UDP下载带宽 多并发支持 稳定性 Tcp通讯网络延迟(小包:32.中包1k.大包1M) UDP通讯网络延迟(小包 ...