旋转多边形是没有前途的,我们考虑旋转敌人,那么答案就是所有人的可行区间长度之和除以$2\pi$

首先对每个敌人找到那些旋转后会落到多边形上的角度,实际上就是圆和一些线段求交,解方程即可,注意判一下落在多边形端点上的情况

把角度排序,每相邻两个角度构成一个区间,在区间内随便取一个角度,把敌人旋转这个角度,判断敌人是否在多边形内,如果是那么整个区间都是可行的

旋转直接套公式:$\left[\matrix{x'\\y'}\right]=\left[\matrix{\cos\theta&-\sin\theta\\\sin\theta&\cos\theta}\right]\left[\matrix{x\\y}\right]$

判断点是否在多边形内:考虑站在这个点,按顺序望向多边形的每个顶点,如果转了$2\pi$弧度就在多边形里,如果转了$0$弧度就在多边形外

注意精度,算夹角时绝对不要用asin或acos,对判别式判断大小不能用eps

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
typedef double du;
const du eps=1e-9,pi2=2*M_PI;
bool equ(du a,du b){return fabs(a-b)<eps;}
bool lt(du a,du b){return a-b<-eps;}
bool inr(du a,du b,du c){
	if(a>c)swap(a,c);
	return lt(a,b)&&lt(b,c);
}
struct point{
	du x,y;
	point(du a=0,du b=0){x=a;y=b;}
};
point operator-(point a,point b){return point(a.x-b.x,a.y-b.y);}
du dot(point a,point b){return a.x*b.x+a.y*b.y;}
du cr(point a,point b){return a.x*b.y-a.y*b.x;}
du len(point a){return sqrt(a.x*a.x+a.y*a.y);}
du dif(point a,point b){
	if(equ(len(a)*len(b),0))return 0;
	if(equ(cr(a,b),0))return lt(0,dot(a,b))?0:-M_PI;
	du f=atan2(b.y,b.x)-atan2(a.y,a.x);
	if(lt(cr(a,b),0)){
		if(lt(0,f))f-=pi2;
	}else if(lt(f,0))
		f+=pi2;
	return f;
}
void eq2(du a,du b,du c,du&d,du&x1,du&x2){
	d=b*b-4*a*c;
	if(d>=0){
		x1=(-b+sqrt(d))/(2*a);
		x2=(-b-sqrt(d))/(2*a);
	}
}
du ang[1010];
int M;
void chk(point u,point a,point b){
	du x1,x2,r;
	r=len(u);
	if(equ(r,len(a)))ang[++M]=dif(u,a);
	if(equ(a.x,b.x)){
		if(lt(r,a.x))return;
		x1=sqrt(r*r-a.x*a.x);
		x2=-x1;
		if(inr(a.y,x1,b.y))ang[++M]=dif(u,point(a.x,x1));
		if(inr(a.y,x2,b.y))ang[++M]=dif(u,point(a.x,x2));
	}else{
		du d,K,B;
		K=(b.y-a.y)/(b.x-a.x);
		B=a.y-K*a.x;
		eq2(K*K+1,2*K*B,B*B-r*r,d,x1,x2);
		if(d<0)return;
		if(inr(a.x,x1,b.x))ang[++M]=dif(u,point(x1,K*x1+B));
		if(inr(a.x,x2,b.x))ang[++M]=dif(u,point(x2,K*x2+B));
	}
}
point e[210],p[510];
int n,m;
#define gao(b,c) if(equ(cr(u-b,u-c),0))return 0;\
				 t+=dif(b-u,c-u);
bool inside(point u){
	du t=0;
	int i;
	for(i=1;i<m;i++){
		gao(p[i],p[i+1])
	}
	gao(p[m],p[1])
	return equ(t,pi2);
}
point rot(point a,du ang){
	return point(a.x*cos(ang)-a.y*sin(ang),a.x*sin(ang)+a.y*cos(ang));
}
#define chk2(a,b,c) if(inside(rot(a,(b+c)*.5)))ans+=(c-b)/pi2;
int main(){
	int i,j;
	du ans;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)scanf("%lf%lf",&e[i].x,&e[i].y);
	for(i=1;i<=m;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
	ans=0;
	for(i=1;i<=n;i++){
		M=0;
		for(j=1;j<m;j++){
			chk(e[i],p[j],p[j+1]);
		}
		chk(e[i],p[m],p[1]);
		if(M<2){
			if(inside(e[i]))ans+=1;
		}else{
			sort(ang+1,ang+M+1);
			for(j=1;j<M;j++){
				chk2(e[i],ang[j],ang[j+1])
			}
			chk2(e[i],ang[M],ang[1]+pi2)
		}
	}
	printf("%.5lf",ans);
}

[LOJ6437]PKUSC的更多相关文章

  1. 【loj6437】 【PKUSC2018】 PKUSC 计算几何

    题目大意:给你一个m个点的简单多边形.对于每个点i∈[1,n],作一个以O点为原点且过点i的圆,求该圆在多边形内的圆弧长度/圆长. 其中n≤200,m≤500. 我们将n个点分开处理. 首先,我们要判 ...

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

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

  3. LOJ6437 PKUSC2018 PKUSC

    带劲的计算几何[这一定是我WC之前开的最后一道计几!!! 每个点画个圆然后看一下交点 然后判断是多边形内还是多边形外 这个就是取圆上中点然后射线法 eps我1e-8才过 不知道为啥有的人说只能开1e- ...

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

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

  5. PKUSC 2018 题解

    PKUSC 2018 题解 Day 1 T1 真实排名 Link Solution 考虑对于每一个人单独算 每一个人有两种情况,翻倍和不翻倍,他的名次不变等价于大于等于他的人数不变 设当前考虑的人的成 ...

  6. [LOJ 6435][PKUSC 2018]星际穿越

    [LOJ 6435][PKUSC 2018]星际穿越 题意 给定 \(n\) 个点, 每个点与 \([l_i,i-1]\) 之间的点建立有单位距离的双向边. \(q\) 组询问从 \(x\) 走到 \ ...

  7. [LOJ 6433][PKUSC 2018]最大前缀和

    [LOJ 6433][PKUSC 2018]最大前缀和 题意 给定一个长度为 \(n\) 的序列, 求把这个序列随机打乱后的最大前缀和的期望乘以 \(n!\) 后对 \(998244353\) 取膜后 ...

  8. [LOJ 6432][PKUSC 2018]真实排名

    [LOJ 6432][PKUSC 2018]真实排名 题意 给定 \(n\) 个选手的成绩, 选中其中 \(k\) 个使他们的成绩翻倍. 对于每个选手回答有多少种方案使得他的排名不发生变化. \(n\ ...

  9. Diary -「PKUSC 2021」游记

      出游回来自然而然(?)地进入生产低谷的兔子只能写写游记了 qwq. Day -1 实时反馈赛制不是为防止你被数据调戏,而是给你调戏数据的机会. --鲁迅   PKU 一贯的 \(32\) 发提交实 ...

随机推荐

  1. 7月23号day15总结

    数据清洗完成之后开始编写前端,通过spring框架将清洗后数据库中的数据显示在页面中. 框架的搭建和js的使用都在学习阶段,

  2. java生成API文档

    1.选择项目右键-Export\javadoc 2.选择生成工具在jdk安装目录下jdk\bin\javadoc.exe 3.在Eclipse里 export 选 JavaDoc,在向导的最后一页的E ...

  3. IntValue()方法 和 ValueOf()方法

    intValue() 1.intValue()是java.lang.Number类的方法,Number是一个抽象类.Java中所有的数值类都继承它.也就是说,不单是Integer有intValue方法 ...

  4. 汕头市队赛 SRM 07 B 好玩的麻将

    B 好玩的麻将 SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂.     KPM上周又打了n场麻将,又控了分使得自己的排名是1..n的一个排列.     但她 ...

  5. [ZOJ2341]Reactor Cooling解题报告|带上下界的网络流|无源汇的可行流

    Reactor Cooling The terrorist group leaded by a well known international terrorist Ben Bladen is bul ...

  6. UITableView学习之辨析两个方法:⓵dequeueReusableCellWithIdentifier与⓶dequeueReusableCellWithIdentifier:forIndexPath:

    使用storyboard显示UITableView时,如果不修改系统默认生成的tableView:cellForRowAtIndexPath:方法中的代码,必须为UITableViewCell注册(填 ...

  7. 【POJ 1719】 Shooting Contest (二分图匹配)

    题目链接 把每一列能射的两行和这一列连边,然后跑一边匈牙利就行了. #include <cstdio> #include <cstring> #include <algo ...

  8. angular2框架搭建,angular-cli使用,angular2学习

    angular红红火火很多年了,一眨眼ng4都出来了,我也只能叹息前端的日新月异,以及感叹自己永远追赶不上时代的步伐,但是没关系,一个优秀的前端不在于他懂的无数的框架,而在于遇到问题时候懂得如何学习, ...

  9. bzoj 3190 维护栈

    我们可以将每一辆赛车看成一条直线,斜率为速度,纵截距为初始位置,那么问题就转化为求这n条直线处于最上面的直线.最上面是指在坐标系中,假设从x轴向下看,能看到的直线,只露一个点也算能看见.那么就类似水平 ...

  10. bzoj 1066 最大流

    将每个石柱拆成两个点,分别是进入的和出去的,两个点之间连石柱的高度 然后每个出去的点连别的石柱的进去的点, 源点连所有蜥蜴所在柱子,每个能跳出去的连汇点,然后最大流就行了 /************* ...