题面

传送门

题解

计算几何的东西我好像都已经忘光了……

首先我们可以把原问题转化为另一个等价的问题:对于每一个敌人,我们以原点为圆心,画一个经过该点的圆,把这个圆在多边形内部的圆弧的度数加入答案。求总的度数是多少

因为这是个简单多边形,我们可以把它给三角形剖分。就是说把每条边都和原点构成一个三角形,然后对圆计算这个三角形的贡献,根据这条边的顺逆时针顺序来决定贡献要加上还是减去。易知最后的贡献就是这个多边形的贡献

那么我们对于每一个圆,暴力枚举多边形的一条边和原点构成的三角形,然后判一下圆弧和三角形的交就行了

//minamoto
#include<bits/stdc++.h>
#define R register
#define eps 1e-3
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
double readdb()
{
R double x=0,y=0.1,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(x=ch-'0';(ch=getc())>='0'&&ch<='9';x=x*10+ch-'0');
for(ch=='.'&&(ch=getc());ch>='0'&&ch<='9';x+=(ch-'0')*y,y*=0.1,ch=getc());
return x*f;
}
const double Pi=acos(-1.0);const int N=505;
int n,m;double ans;
inline bool dcmp(const double &a,const double &b){return fabs(a-b)<eps;}
struct node{
double x,y;
node(){}
node(R double X,R double Y):x(X),y(Y){}
inline node operator +(const node &b)const{return node(x+b.x,y+b.y);}
inline node operator -(const node &b)const{return node(x-b.x,y-b.y);}
inline node operator *(const double &b)const{return node(x*b,y*b);}
inline node operator /(const double &b)const{return node(x/b,y/b);}
inline double operator *(const node &b)const{return x*b.y-y*b.x;}
friend double dot(const node &a,const node &b){return a.x*b.x+a.y*b.y;}
inline double norm(){return sqrt(x*x+y*y);}
}p[N],c[N];
void calc(node a,node b,double r){
int f=(a*b<0)?-1:1;
if(max(a.norm(),b.norm())<r)return;
double theta=acos(dot(a,b)/(a.norm()*b.norm()));
double h=fabs(a*b)/(b-a).norm();
if(h>=r)return ans+=theta*f,void();
double beta=acos(dot(a-b,node(-b.x,-b.y))/((a-b).norm()*b.norm()));
double alpha=acos(dot(b-a,node(-a.x,-a.y))/((b-a).norm()*a.norm()));
double t=asin(h/r),s=0;
if(t>beta)s+=t-beta;if(t>alpha)s+=t-alpha;
s=min(s,theta);
ans+=f*s;
}
bool ck(node a,node b){
node c(1,0);
if(a.y<b.y)swap(a,b);
return c*a>0&&b*c>0&&b*a>0;
}
void solve(){
fp(i,1,m)if(!dcmp(c[i]*c[i+1],0))
fp(j,1,n)if(!dcmp(p[j].norm(),0))calc(c[i],c[i+1],p[j].norm());
fp(j,1,n)if(dcmp(p[j].norm(),0)){
bool flag=1;int t=0;
fp(i,1,m)if(dcmp((c[i]-p[j])*(c[i+1]-p[j]),0)){
if(dot(c[i]-p[j],c[i+1]-p[j])<=0){flag=0;break;}
}else{
if(dcmp(c[i].y,0))t+=(c[i].x>0);
else t+=ck(c[i],c[i+1]);
}
if(flag&&(t&1))ans+=2*Pi;
}
ans/=2*Pi;
printf("%.5lf\n",ans);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
fp(i,1,n)p[i].x=readdb(),p[i].y=readdb();
fp(i,1,m)c[i].x=readdb(),c[i].y=readdb();
c[m+1]=c[1];
solve();
return 0;
}

loj#6437. 「PKUSC2018」PKUSC(计算几何)的更多相关文章

  1. LOJ#6437. 「PKUSC2018」PKUSC

    题面 题意转化为: 判断每个点所在的圆有多长的弧度角位于多边形内部. 然后就很暴力了. 每个点P,直接找到多边形和这个圆的所有交点,按照距离P的角度排序. 找交点,直接联立二元二次方程组.... 需要 ...

  2. 【LOJ】#6437. 「PKUSC2018」PKUSC

    题解 我们把这个多边形三角形剖分了,和统计多边形面积一样 每个三角形有个点是原点,把原点所对应的角度算出来,记为theta 对于一个点,相当于半径为这个点到原点的一个圆,圆弧上的弧度为theta的一部 ...

  3. LOJ6437. 「PKUSC2018」PKUSC [计算几何]

    LOJ 思路 显然多边形旋转可以变成点旋转,不同的点的贡献可以分开计算. 然后就变成了要求一个圆在多边形内的弧长. 考虑把交点全都求出来,那么两个交点之间的状态显然是相同的,可以直接把圆弧上的中点的状 ...

  4. [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC

    [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC 试题描述 九条可怜是一个爱玩游戏的女孩子. 最近她在玩一个无双割草类的游戏,平面上有 \(n\) 个敌人,每一个敌人的坐标为 ...

  5. LOJ #6436. 「PKUSC2018」神仙的游戏(字符串+NTT)

    题面 LOJ #6436. 「PKUSC2018」神仙的游戏 题解 参考 yyb 的口中的长郡最强选手 租酥雨大佬的博客 ... 一开始以为 通配符匹配 就是类似于 BZOJ 4259: 残缺的字符串 ...

  6. LOJ #6435. 「PKUSC2018」星际穿越(倍增)

    题面 LOJ#6435. 「PKUSC2018」星际穿越 题解 参考了 这位大佬的博客 这道题好恶心啊qwq~~ 首先一定要认真阅读题目 !! 注意 \(l_i<r_i<x_i\) 这个条 ...

  7. LOJ #6432. 「PKUSC2018」真实排名(组合数)

    题面 LOJ #6432. 「PKUSC2018」真实排名 注意排名的定义 , 分数不小于他的选手数量 !!! 题解 有点坑的细节题 ... 思路很简单 , 把每个数分两种情况讨论一下了 . 假设它为 ...

  8. Loj#6434「PKUSC2018」主斗地(搜索)

    题面 Loj 题解 细节比较多的搜索题. 首先现将牌型暴力枚举出来,大概是\(3^{16}\)吧. 然后再看能打什么,简化后无非就三种决策:单牌,\(3+x\)和\(4+x\). 枚举网友打了几张\( ...

  9. Loj#6433「PKUSC2018」最大前缀和(状态压缩DP)

    题面 Loj 题解 先转化题意,其实这题在乘了\(n!\)以后就变成了全排列中的最大前缀和的和(有点拗口).\(n\leq20\),考虑状压\(DP\) 考虑一个最大前缀和\(\sum\limits_ ...

随机推荐

  1. ghld

  2. 02-17 位图验证码(一般处理程序)+AJAX

    建立一个空网站,在设计界面工具箱中拖入一个TextBox工具,一个按钮,外加一个Image图片工具(充当数字.字母以图片形式).但是这样做出来的验证码会出现一个问题,每当点击一下按钮,界面自动提交一遍 ...

  3. java中的报错机制

    异常:Exception,程序运行过程中因为一些原因,使得程序无法运行下去 注意:在程序能够运行起来的情况,不是程序编译通不过 举例:读文件,点击一个按钮,文件不存在:访问数据库服务器,数据库服务器停 ...

  4. 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 5 Octave Tutorial—5.4 绘制数据图

    5.4 绘制数据图 参考视频: 5 - 4 - Plotting Data (10 min) 5.4.1 绘制曲线 1.画一个sin曲线 >> t = [:0.01:0.98]; > ...

  5. python文件处理-读、写

    Python中文件处理的操作包括读.写.修改,今天我们一起来先学习下读和写操作. 一.文件的读操作 例一: #文件读操作 f = open(file="first_blog.txt" ...

  6. 张超超OC基础回顾02_成员变量(属性),局部变量,全局变量的区别

    成员变量: 写在类声明的大括号中的变量, 我们称之为 成员变量(属性, 实例变量) 成员变量只能通过对象来访问 注意: 成员变量不能离开类, 离开类之后就不是成员变量 成员变量不能在定义的同时进行初始 ...

  7. 面试题:Java多线程必须掌握的十个问题 背1

    一.进程与线程?并行与并发? 进程代表一个运行中的程序,是资源分配与调度的基本单位.进程有三大特性: 1.独立性:独立的资源,私有的地址空间,进程间互不影响. 2.动态性:进程具有生命周期. 3.并发 ...

  8. Linux查看内存,负载状态

    Linux查看内存,负载状态 查看内存使用情况  www.ahlinux.com cat /proc/meminfo MemTotal:       16332644 kB MemFree:     ...

  9. suse10配置SSH无密码登录的方法

    RSH配置(集群中的每台机器执行以下操作) 1.因SUSE LINUX不自带RSH-SERVER服务,所以首先要去从www.rpmfind.net 下载rsh-server服务的RPM包. 然后切换到 ...

  10. CF 961G Partitions

    推不动式子 我们考虑每一个$w_i$对答案的贡献,因为题目中定义集合的价值为$W(S) = \left | S \right |\sum_{x \in S}w_x$,这个系数$\left | S \r ...