博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 5130 Signal Interference(计算几何 + 模板)
阅读量:5036 次
发布时间:2019-06-12

本文共 6708 字,大约阅读时间需要 22 分钟。

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

题目链接

Description

Two countries A-Land and B-Land are at war. The territory of A-Land is a simple polygon with no more than 500 vertices. For military use, A-Land constructed a radio tower (also written as A), and it's so powerful that the whole country was under its signal. To interfere A-Land's communication, B-Land decided to build another radio tower (also written as B). According to an accurate estimation, for any point P, if the euclidean distance between P and B is no more than k (0.2 ≤ k < 0.8) times of the distance between P and A, then point P is not able to receive clear signals from A, i.e. be interfered. Your task is to calculate the area in A-Land's territory that are under B-Land's interference.

Input

There are no more than 100 test cases in the input.

In each test case, firstly you are given a positive integer N indicating the amount of vertices on A-Land's territory, and an above mentioned real number k, which is rounded to 4 digits after the decimal point.
Then N lines follow. Each line contains two integers x and y (|x|, |y| ≤ 1000), indicating a vertex's coordinate on A's territory, in counterclockwise or clockwise order.
The last two lines of a test case give radio tower A and B's coordinates in the same form as vertexes' coordinates. You can assume that A is not equal to B.

Output

For each test case, firstly output the case number, then output your answer in one line following the format shown in sample. Please note that there is a blank after the ':'.

Your solution will be accepted if its absolute error or relative error is no more than 10-6.
This problem is special judged.

Sample Input

4 0.5000

-1 -1
1 -1
1 1
-1 1
0 0
-1 0

Sample Output

Case 1: 0.2729710441

题意:

给你n个点按照顺时针或者逆时针排序围成多边形,A,B点,让你计算从某点到B点的距离是到A距离的K倍,求这个图形和多边形的相交的面积。

题解:

求的点带入,化简就是一个圆,然后就是圆和多边形的面积交。套模板。

代码:

#include 
#define eps 1e-8using namespace std;struct Point{ double x,y; Point(double x=0, double y=0):x(x),y(y) {} void input() { scanf("%lf%lf",&x,&y); }};typedef Point Vector;struct Circle{ Point c; double r; Circle(){} Circle(Point c,double r):c(c),r(r) {} Point point(double a) { return Point(c.x + cos(a)*r, c.y + sin(a)*r); } void input() { scanf("%lf%lf%lf",&c.x,&c.y,&r); }};int dcmp(double x) { if(x < -eps) return -1; if(x > eps) return 1; return 0;}template
T sqr(T x) { return x * x;}Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; }bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; }bool operator == (const Point& a, const Point& b) { return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; }double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }double Length(Vector A) { return sqrt(Dot(A, A)); }double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); }double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }Vector VectorUnit(Vector x){ return x / Length(x);}Vector Normal(Vector x) { return Point(-x.y, x.x) / Length(x);}double angle(Vector v) { return atan2(v.y, v.x); }bool OnSegment(Point P, Point A, Point B) { return dcmp(Cross(A-P,B-P)) == 0 && dcmp(Dot(A-P,B-P)) < 0;}double DistanceToSeg(Point P, Point A, Point B){ if(A == B) return Length(P-A); Vector v1 = B-A, v2 = P-A, v3 = P-B; if(dcmp(Dot(v1, v2)) < 0) return Length(v2); if(dcmp(Dot(v1, v3)) > 0) return Length(v3); return fabs(Cross(v1, v2)) / Length(v1);}double DistanceToLine(Point P, Point A, Point B){ Vector v1 = B-A, v2 = P-A; return fabs(Cross(v1,v2)) / Length(v1);}Point DisP(Point A, Point B){ return Length(B-A);}bool SegmentIntersection(Point A,Point B,Point C,Point D) { return max(A.x,B.x) >= min(C.x,D.x) && max(C.x,D.x) >= min(A.x,B.x) && max(A.y,B.y) >= min(C.y,D.y) && max(C.y,D.y) >= min(A.y,B.y) && dcmp(Cross(C-A,B-A)*Cross(D-A,B-A)) <= 0 && dcmp(Cross(A-C,D-C)*Cross(B-C,D-C)) <= 0;}Point Zero = Point(0,0);//sum_ans !!!!!!!fabs()double TriAngleCircleInsection(Circle C, Point A, Point B){ Vector OA = A-C.c, OB = B-C.c; Vector BA = A-B, BC = C.c-B; Vector AB = B-A, AC = C.c-A; double DOA = Length(OA), DOB = Length(OB),DAB = Length(AB), r = C.r; if(dcmp(Cross(OA,OB)) == 0) return 0; if(dcmp(DOA-C.r) < 0 && dcmp(DOB-C.r) < 0) return Cross(OA,OB)*0.5; else if(DOB < r && DOA >= r) { double x = (Dot(BA,BC) + sqrt(r*r*DAB*DAB-Cross(BA,BC)*Cross(BA,BC)))/DAB; double TS = Cross(OA,OB)*0.5; return asin(TS*(1-x/DAB)*2/r/DOA)*r*r*0.5+TS*x/DAB; } else if(DOB >= r && DOA < r) { double y = (Dot(AB,AC)+sqrt(r*r*DAB*DAB-Cross(AB,AC)*Cross(AB,AC)))/DAB; double TS = Cross(OA,OB)*0.5; return asin(TS*(1-y/DAB)*2/r/DOB)*r*r*0.5+TS*y/DAB; } else if(fabs(Cross(OA,OB)) >= r*DAB || Dot(AB,AC) <= 0 || Dot(BA,BC) <= 0) { if(Dot(OA,OB) < 0) { if(Cross(OA,OB) < 0) return (-acos(-1.0)-asin(Cross(OA,OB)/DOA/DOB))*r*r*0.5; else return ( acos(-1.0)-asin(Cross(OA,OB)/DOA/DOB))*r*r*0.5; } else return asin(Cross(OA,OB)/DOA/DOB)*r*r*0.5; } else { double x = (Dot(BA,BC)+sqrt(r*r*DAB*DAB-Cross(BA,BC)*Cross(BA,BC)))/DAB; double y = (Dot(AB,AC)+sqrt(r*r*DAB*DAB-Cross(AB,AC)*Cross(AB,AC)))/DAB; double TS = Cross(OA,OB)*0.5; return (asin(TS*(1-x/DAB)*2/r/DOA)+asin(TS*(1-y/DAB)*2/r/DOB))*r*r*0.5 + TS*((x+y)/DAB-1); }}Point s[600],A,B ;int main(){ int n ; int _t = 0; while (~scanf("%d",&n)){ double k ; _t++ ; scanf("%lf",&k) ; for (int i = 1;i <= n; i++) s[i].input(); A.input();B.input(); s[n+1] = s[1]; double D,E,F; D = (2.0*k*k*A.x - 2.0*B.x)/(1.0-k*k) ; E = (2.0*k*k*A.y - 2.0*B.y)/(1.0-k*k) ; F = (B.x*B.x+B.y*B.y-k*k*(A.x*A.x+A.y*A.y))/(1.0-k*k) ; Circle C = Circle(Point(D*(-0.5),E*(-0.5)),sqrt(D*D+E*E-4.0*F)*0.5) ; double ans = 0.0; for (int i = 1; i <= n; i++){ ans = ans + TriAngleCircleInsection(C,s[i],s[i+1]) ; } printf("Case %d: %.10lf\n",_t,fabs(ans)) ; } return 0;}
posted @
2016-10-15 00:04 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/thecoollight/p/5962566.html

你可能感兴趣的文章
设计模式六大原则(5):迪米特法则
查看>>
对Feature的操作插入添加删除
查看>>
javascript String
查看>>
ecshop 系统信息在哪个页面
查看>>
【转】码云source tree 提交超过100m 为什么大文件推不上去
查看>>
Oracle数据库的增、删、改、查
查看>>
阿里市值超越亚马逊 马云开启下半场技术理想
查看>>
MySql执行分析
查看>>
git使用中的问题
查看>>
yaml文件 .yml
查看>>
linux字符集修改
查看>>
phpcms 添加自定义表单 留言
查看>>
mysql 优化
查看>>
读书笔记 ~ Nmap渗透测试指南
查看>>
WCF 配置文件
查看>>
动态调用WCF服务
查看>>
oracle导出/导入 expdp/impdp
查看>>
类指针
查看>>
css修改滚动条样式
查看>>
2018.11.15 Nginx服务器的使用
查看>>