3034. 望远镜

题目链接

3034. 望远镜

Updog 正在用望远镜观察一个飞行物。

望远镜的视野可以描述为一个圆,其圆心位于原点,半径为 R

飞行物可视作一个 N 个顶点的简单多边形。

Updog 希望知道飞行物处于望远镜视野之内的部分的面积。

输入格式

本题包含多组测试数据。

对于每组数据,第一行包含一个实数 R

第二行包含一个整数 N

接下来 N 行,每行包含两个实数 xi,yi,表示一个顶点的坐标。相邻两行描述的顶点在多边形中也是相邻的。

输出格式

每组数据输出一行一个实数,表示答案。

结果四舍五入保留两位小数。

数据范围

每个测试点最多包含 10 组数据。
3N50,
0.1R1000,
1000xi,yi1000

输入样例:

10 3 0 20 10 0 -10 0

输出样例:

144.35

解题思路

三角剖分

三角剖分是一种类似于求任意一个多边形面积的算法,即将一个多边形分为若干个三角形,且这些三角形都有一个公共点,沿着某个方面求解得到的面积和即为多边形的面积
本题要求求一个圆和多边形的面积交,可以将圆的圆心作为公共点,将多边形三角剖分,本题即求解若干个三角形和圆的面积交的和,且这些三角形都有一个端点在圆心上,然后分如下几种情况讨论计算即可:(感谢 Anoxia_3 同学的图)

image

  • 时间复杂度:O(n)

代码

// Problem: 望远镜 // Contest: AcWing // URL: https://www.acwing.com/problem/content/description/3037/ // Memory Limit: 64 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=55; const double eps=1e-8,pi=acos(-1); typedef pair<double,double> PDD; int n; double R; PDD a[N],p; PDD operator+(PDD a,PDD b) { return {a.fi+b.fi,a.se+b.se}; } PDD operator-(PDD a,PDD b) { return {a.fi-b.fi,a.se-b.se}; } PDD operator*(PDD a,double t) { return {a.fi*t,a.se*t}; } PDD operator/(PDD a,double t) { return {a.fi/t,a.se/t}; } double operator*(PDD a,PDD b) { return a.fi*b.se-b.fi*a.se; } double operator&(PDD a,PDD b) { return a.fi*b.fi+a.se*b.se; } int sign(double x) { if(fabs(x)<eps)return 0; if(x<0)return -1; return 1; } int dcmp(double x,double y) { if(fabs(x-y)<eps)return 0; if(x<y)return -1; return 1; } double area(PDD a,PDD b,PDD c) { return (b-a)*(c-a); } double get_len(PDD a) { return sqrt(a&a); } double get_dist(PDD a,PDD b) { return get_len(b-a); } PDD rotate(PDD a,double angle) { return {a.fi*cos(angle)+a.se*sin(angle),-a.fi*sin(angle)+a.se*cos(angle)}; } PDD get_line_intersection(PDD p,PDD v,PDD q,PDD w) { PDD u=p-q; double t=w*u/(v*w); return p+v*t; } bool on_segment(PDD p,PDD a,PDD b) { return !sign((p-a)*(p-b))&&sign((p-a)&(p-b))<=0; } PDD norm(PDD a) { return a/get_len(a); } double get_circle_line_intersection(PDD a,PDD b,PDD &pa,PDD &pb) { PDD o=get_line_intersection(a,b-a,p,rotate(b-a,pi/2)); double mind=get_dist(p,o); if(!on_segment(o,a,b))mind=min(get_dist(p,a),get_dist(p,b)); if(dcmp(R,mind)<=0)return mind; double len=sqrt(R*R-get_dist(p,o)*get_dist(p,o)); pa=o+norm(a-b)*len; pb=o+norm(b-a)*len; return mind; } double get_sentor(PDD a,PDD b) { double angle=acos((a&b)/get_len(a)/get_len(b)); if(sign(a*b)<0)angle=-angle; return R*R*angle/2; } double get_circle_triangle_area(PDD a,PDD b) { double da=get_dist(p,a),db=get_dist(p,b); if(dcmp(da,R)<=0&&dcmp(db,R)<=0)return a*b/2; if(!sign(a*b))return 0; PDD pa={0,0},pb={0,0}; double mind=get_circle_line_intersection(a,b,pa,pb); if(dcmp(R,mind)<=0)return get_sentor(a,b); if(dcmp(R,da)>=0)return a*pb/2+get_sentor(pb,b); if(dcmp(R,db)>=0)return pa*b/2+get_sentor(a,pa); return get_sentor(a,pa)+pa*pb/2+get_sentor(pb,b); } double triangulate() { double res=0; for(int i=0;i<n;i++)res+=get_circle_triangle_area(a[i],a[(i+1)%n]); return fabs(res); } int main() { while(~scanf("%lf%d",&R,&n)) { for(int i=0;i<n;i++)scanf("%lf%lf",&a[i].fi,&a[i].se); printf("%.2lf\n",triangulate()); } return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/16919001.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示