博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LOJ#6437. 「PKUSC2018」PKUSC
阅读量:6291 次
发布时间:2019-06-22

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

题意转化为:

判断每个点所在的圆有多长的弧度角位于多边形内部。

然后就很暴力了。

每个点P,直接找到多边形和这个圆的所有交点,按照距离P的角度排序。

找交点,直接联立二元二次方程组。。。。

 

需要判断一段弧是否在多边形内部。

向量随机旋转角度,判断点是否在多边形内部即可。

如果该点在多边形边上,返回-1,重新旋转。

由于double,所以不会出现射线在多边形边上情况。

 

注意:

(0,0)要特判是否在多边形内部。+eps判断

#include
#define reg register intusing namespace std;// using namespace Modulo;namespace Miracle{const int N=505;const double eps=1e-8;const double inf=1e8;const double Pi=acos(-1);int n,m;struct po{ double x,y; po(){} po(double xx,double yy){ x=xx;y=yy; } double friend operator *(po a,po b){ return a.x*b.y-a.y*b.x; } double dis(){ return sqrt(x*x+y*y); } po friend operator -(po a,po b){ return po(a.x-b.x,a.y-b.y); } double deg(){ return atan2(y,x); } po xuan(double d){ double nd=deg()-d; double len=dis(); return po(len*cos(nd),len*sin(nd)); } void op(){ cout<<"("<
<<","<
<<")"<
=L.A.x&&c.x<=L.B.x+eps){ if(L.k==inf) { if(c.y+eps>=L.A.y&&c.y<=L.B.y+eps) return 1; } else{
double ny=L.f(c.x); if(fabs(ny-c.y)
=0&&d2<=0){ return d1-d2; }else if(d1>=0&&d2>=0){ if(d1>d2) return d1-d2; return 2*Pi-(d2-d1); }else if(d1<=0&&d2>=0){ return 2*Pi-(d2-d1); }else if(d1<=0&&d2<=0){ if(d1>d2) return (d1-d2); return 2*Pi-(d2-d1); } return 0;}double sui(){ return (double)rand()/(RAND_MAX);}double calc(po a){ int cnt=0; double r=a.dis(); if(r==0){ a.y+=eps; if(in(a)==1) return 2*Pi; else return 0; } for(reg i=1;i<=m;++i){ if(l[i].k
=0){ double x1=(-B+sqrt(deta))/(2*A),x2=(-B-sqrt(deta))/(2*A); po now=po(x1,l[i].f(x1)); if(on(now,l[i])) { cur[++cnt]=node(cha(a.deg(),now.deg()),now); } now=po(x2,l[i].f(x2)); if(on(now,l[i])){ cur[++cnt]=node(cha(a.deg(),now.deg()),now); } } }else{ double lp=r*r-l[i].A.x*l[i].A.x; double X=l[i].A.x; if(lp>0){ double Y=sqrt(lp); po now=po(X,Y); if(on(now,l[i])) { cur[++cnt]=node(cha(a.deg(),now.deg()),now); } Y=-sqrt(lp); now=po(X,Y); if(on(now,l[i])){ cur[++cnt]=node(cha(a.deg(),now.deg()),now); } } } } cur[++cnt]=node(0,a); cur[++cnt]=node(2*Pi,a); sort(cur+1,cur+cnt+1); double ret=0; for(reg i=2;i<=cnt;++i){ double d=cur[i].c-cur[i-1].c; if(d<0.0000001) continue; po now=cur[i-1].P; int tmp=-1; while(tmp==-1){ double z=d*sui(); now=cur[i-1].P.xuan(z); tmp=in(now); } if(tmp==1){ ret+=d; } } return ret;}int main(){ srand((unsigned long long)new char); cin>>n>>m; for(reg i=1;i<=n;++i){ double x,y; scanf("%lf%lf",&x,&y); q[i]=po(x,y); } for(reg i=1;i<=m;++i){ double x,y; scanf("%lf%lf",&x,&y); p[i]=po(x,y); } for(reg i=1;i<=m;++i){ int nxt=(i==m)?1:i+1; l[i].A=p[i];l[i].B=p[nxt]; if(p[i].x>p[nxt].x||(p[i].x==p[nxt].x&&p[i].y>p[nxt].y)) swap(l[i].A,l[i].B); if(p[i].x==p[nxt].x){ l[i].k=inf; }else{ l[i].k=(p[nxt].y-p[i].y)/(p[nxt].x-p[i].x); l[i].b=((p[nxt].x*p[i].y)-(p[i].x*p[nxt].y))/(p[nxt].x-p[i].x); } } double ans=0.0; for(reg i=1;i<=n;++i){ ans+=calc(q[i]); } ans=ans/(2*Pi); printf("%.5lf",ans); return 0;}}signed main(){ Miracle::main(); return 0;}/* Author: *Miracle**/

 

转载于:https://www.cnblogs.com/Miracevin/p/11021938.html

你可能感兴趣的文章
【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays
查看>>
精度 Precision
查看>>
Android——4.2 - 3G移植之路之 APN (五)
查看>>
Linux_DHCP服务搭建
查看>>
[SilverLight]DataGrid实现批量输入(like Excel)(补充)
查看>>
秋式广告杀手:广告拦截原理与杀手组织
查看>>
翻译 | 摆脱浏览器限制的JavaScript
查看>>
闲扯下午引爆乌云社区“盗窃”乌云币事件
查看>>
02@在类的头文件中尽量少引入其他头文件
查看>>
JAVA IO BIO NIO AIO
查看>>
input checkbox 复选框大小修改
查看>>
BOOT.INI文件参数
查看>>
vmstat详解
查看>>
新年第一镖
查看>>
unbtu使用笔记
查看>>
OEA 中 WPF 树型表格虚拟化设计方案
查看>>
Android程序开发初级教程(一) 开始 Hello Android
查看>>
使用Gradle打RPM包
查看>>
“我意识到”的意义
查看>>
淘宝天猫上新辅助工具-新品填表
查看>>