LOJ#6437. 「PKUSC2018」PKUSC
题意转化为:
判断每个点所在的圆有多长的弧度角位于多边形内部。
然后就很暴力了。
每个点P,直接找到多边形和这个圆的所有交点,按照距离P的角度排序。
找交点,直接联立二元二次方程组。。。。
需要判断一段弧是否在多边形内部。
向量随机旋转角度,判断点是否在多边形内部即可。
如果该点在多边形边上,返回-1,重新旋转。
由于double,所以不会出现射线在多边形边上情况。
注意:
(0,0)要特判是否在多边形内部。+eps判断
#include<bits/stdc++.h>
#define reg register int
using namespace std;
// using namespace Modulo;
namespace Miracle{
const int N=;
const double eps=1e-;
const double inf=1e8;
const double Pi=acos(-);
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<<"("<<x<<","<<y<<")"<<endl;
}
}p[N],q[N];
struct node{
po P;
double c;
node(){}
node(double cc,po PP){
c=cc;P=PP;
}
bool friend operator <(node a,node b){
return a.c<b.c;
}
}cur[N];
struct line{
double k,b;
po A,B;
double f(double x){
if(k<inf) return k*x+b;
return A.y;
}
}l[N];
bool on(po c,line L){//c on L?
if(c.x+eps>=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 ;
}
else{double ny=L.f(c.x);
if(fabs(ny-c.y)<eps) return ;}
}
return ;
}
bool jiao(line a,line b){
double c1=(a.A-b.A)*(a.A-b.B),c2=(a.B-b.A)*(a.B-b.B);
double c3=(b.A-a.A)*(b.A-a.B),c4=(b.B-a.A)*(b.B-a.B);
if(c1*c2<=&&c3*c4<=) return true;
return false;
}
int in(po a){
int cnt=;
line now;
now.k=;now.b=a.y;
now.A=a;now.B=po(inf,a.y);
for(reg i=;i<=m;++i){
if(on(a,l[i])) return -;
if(jiao(now,l[i])) ++cnt;
}
if(cnt&) return ;
return ;
}
double cha(double d1,double d2){
if(d1>=&&d2<=){
return d1-d2;
}else if(d1>=&&d2>=){
if(d1>d2) return d1-d2;
return *Pi-(d2-d1);
}else if(d1<=&&d2>=){
return *Pi-(d2-d1);
}else if(d1<=&&d2<=){
if(d1>d2) return (d1-d2);
return *Pi-(d2-d1);
}
return ;
}
double sui(){
return (double)rand()/(RAND_MAX);
}
double calc(po a){
int cnt=;
double r=a.dis();
if(r==){
a.y+=eps;
if(in(a)==) return *Pi;
else return ;
}
for(reg i=;i<=m;++i){
if(l[i].k<inf){
double A=(+l[i].k*l[i].k);
double B=*l[i].k*l[i].b;
double C=l[i].b*l[i].b-r*r;
double deta=B*B-*A*C;
if(deta>=){
double x1=(-B+sqrt(deta))/(*A),x2=(-B-sqrt(deta))/(*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>){
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(,a);
cur[++cnt]=node(*Pi,a);
sort(cur+,cur+cnt+);
double ret=;
for(reg i=;i<=cnt;++i){
double d=cur[i].c-cur[i-].c;
if(d<0.0000001) continue;
po now=cur[i-].P;
int tmp=-;
while(tmp==-){
double z=d*sui();
now=cur[i-].P.xuan(z);
tmp=in(now);
}
if(tmp==){
ret+=d;
}
}
return ret; }
int main(){
srand((unsigned long long)new char);
cin>>n>>m;
for(reg i=;i<=n;++i){
double x,y;
scanf("%lf%lf",&x,&y);
q[i]=po(x,y);
}
for(reg i=;i<=m;++i){
double x,y;
scanf("%lf%lf",&x,&y);
p[i]=po(x,y);
}
for(reg i=;i<=m;++i){
int nxt=(i==m)?:i+;
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=;i<=n;++i){
ans+=calc(q[i]);
}
ans=ans/(*Pi);
printf("%.5lf",ans);
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
*/
LOJ#6437. 「PKUSC2018」PKUSC的更多相关文章
- loj#6437. 「PKUSC2018」PKUSC(计算几何)
题面 传送门 题解 计算几何的东西我好像都已经忘光了-- 首先我们可以把原问题转化为另一个等价的问题:对于每一个敌人,我们以原点为圆心,画一个经过该点的圆,把这个圆在多边形内部的圆弧的度数加入答案.求 ...
- 【LOJ】#6437. 「PKUSC2018」PKUSC
题解 我们把这个多边形三角形剖分了,和统计多边形面积一样 每个三角形有个点是原点,把原点所对应的角度算出来,记为theta 对于一个点,相当于半径为这个点到原点的一个圆,圆弧上的弧度为theta的一部 ...
- [LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC
[LOJ#6437][BZOJ5373]「PKUSC2018」PKUSC 试题描述 九条可怜是一个爱玩游戏的女孩子. 最近她在玩一个无双割草类的游戏,平面上有 \(n\) 个敌人,每一个敌人的坐标为 ...
- LOJ #6436. 「PKUSC2018」神仙的游戏(字符串+NTT)
题面 LOJ #6436. 「PKUSC2018」神仙的游戏 题解 参考 yyb 的口中的长郡最强选手 租酥雨大佬的博客 ... 一开始以为 通配符匹配 就是类似于 BZOJ 4259: 残缺的字符串 ...
- LOJ #6435. 「PKUSC2018」星际穿越(倍增)
题面 LOJ#6435. 「PKUSC2018」星际穿越 题解 参考了 这位大佬的博客 这道题好恶心啊qwq~~ 首先一定要认真阅读题目 !! 注意 \(l_i<r_i<x_i\) 这个条 ...
- LOJ #6432. 「PKUSC2018」真实排名(组合数)
题面 LOJ #6432. 「PKUSC2018」真实排名 注意排名的定义 , 分数不小于他的选手数量 !!! 题解 有点坑的细节题 ... 思路很简单 , 把每个数分两种情况讨论一下了 . 假设它为 ...
- Loj#6434「PKUSC2018」主斗地(搜索)
题面 Loj 题解 细节比较多的搜索题. 首先现将牌型暴力枚举出来,大概是\(3^{16}\)吧. 然后再看能打什么,简化后无非就三种决策:单牌,\(3+x\)和\(4+x\). 枚举网友打了几张\( ...
- Loj#6433「PKUSC2018」最大前缀和(状态压缩DP)
题面 Loj 题解 先转化题意,其实这题在乘了\(n!\)以后就变成了全排列中的最大前缀和的和(有点拗口).\(n\leq20\),考虑状压\(DP\) 考虑一个最大前缀和\(\sum\limits_ ...
- Loj#6432「PKUSC2018」真实排名(二分查找+组合数)
题面 Loj 题解 普通的暴力是直接枚举改或者不改,最后在判断最后对哪些点有贡献. 而这种方法是很难优化的.所以考虑在排序之后线性处理.首先先假设没有重复的元素 struct Node { int p ...
随机推荐
- shell脚本输出空心等腰三角形
第一种:(for循环) #!/bin/bash#空心等腰三角形arr=9 #定义金字塔的层数for ((i=1;i<=$arr;i++))do for ((j=1;j<=$(($arr-$ ...
- 换盘符cd的用法
如果是在本盘内切换文件夹,直接使用cd 后面跟地址即可. 如果是跨区切换地址,cd 后面就需要跟/d,斜杠d, /d就代表着跨分区切换地址. cd /d d:\ C:\ProgramData\Anac ...
- Tools: windbg 使用指南
windbg使用 符号表C:\Symbols; SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols 系统变量_NT_SYMBOL_PAT ...
- vue $emit 子传父
我们使用子组件传递值给父组件使用 $emit 代码 <!DOCTYPE html> <html lang="en"> <head> <me ...
- Linux service,挂载,定时任务等常用服务
一.防火墙 防火墙根据配置文件/etc/sysconfig/iptables 来控制本机的“出.入”网络访问行为 其对行为的配置策略有四个策 1. 基础必备技能 查看防火墙状态 s ...
- 七种数据库中Select Top的使用方法 (只显示数据库的几条记录)
七种数据库中Select Top的使用方法 1. Oracle数据库 SELECT * FROM TABLENAME WHERE ROWNUM <= N 2. Infomix数据库 SELE ...
- R语言 变量
R语言变量 变量为我们提供了我们的程序可以操作的命名存储. R语言中的变量可以存储原子向量,原子向量组或许多Robject的组合. 有效的变量名称由字母,数字和点或下划线字符组成. 变量名以字母或不以 ...
- 微信小程序布局篇
刚刚接触小程序,小程序与HTML5有一定的差别,小程序就几个标签,而HTML5一大堆标签,还不断更新,但是新增标签功能强大.做一下微信小程序的布局练练手.感觉还是挺不错的,也封装了很多东西功能出来,与 ...
- thinkphp 日志驱动
日志驱动默认的命名空间位于Think\Log\Driver,驱动类需要实现的接口方法包括: 方法 说明 架构方法 __construct($config=array()) 写入方法 write($lo ...
- 取对数求阶乘位数——lightoj1045
/* 求 n! 在base进制下的位数 取对数,用换底公式,预处理对数前缀和 b^x = n! x = log_b(n!) = log_10(n!)/log_10(b) 对x向上取整即可 */ #in ...