bzoj4445 小凸想跑步
半平面交,注意直线方向!!!
对于凸包上任意一条边$LINE(p_i,p_{i+1})$都有$S_{\Delta{p_i} {p_{i + 1}}p} < S_{\Delta{p_0} {p_1}p}$
如果我们用叉积来算面积:
$P=(x,y)$
$A=p_0=(x_1,y_1)$
$B=p_1=(x_2,y_2)$
$C=p_{i+1}=(x_3,y_3)$(至于为什么是C为i+1而不是D为i+1,画画图就知道了)
$D=p_i=(x_4,y_4)$
就有不等式:
$(x-x_2,y-y_2)(x-x_1,y-y_1)\leqslant(x-x_3,y-y_3)(x-x_4,y-y_4)$
$\Rightarrow$
$(x-x_2)(y-y_1)-(y-y_2)(x-x_1) \leqslant (x-x_3)(y-y_4)-(y-y_3)(x-x_4)$
$\Rightarrow$
$(-y_1+y_2-y_3-y_4)x+(x_1-x_2+x_3-x_4)y+$$(x_2\times y_1-y_2\times x_1)+(x_4\times y_3-y_4\times x_3) \leqslant 0$
$\Rightarrow$
$(-y_1+y_2-y_3-y_4)x+(x_1-x_2+x_3-x_4)y+\overrightarrow B\times\overrightarrow A+\overrightarrow D\times \overrightarrow C\leqslant 0$
就得到了一个半平面
交一交即可
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<set>
#include<queue>
#define op operator
#define re(i,l,r) for(int i=(l);i<=(r);i++)
#define rre(i,r,l) for(int i=(r);i>=(l);i--)
using namespace std;
template <typename Q>
void inin(Q &ret)
{
ret=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=;ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
ret=f?-ret:ret;
}
int shurux,shuruy;
const double eps=1e-;
int dcmp(const double &x){return abs(x)<eps?:x<?-:;}
const double pi=acos(-);
const double f(const double &a){return a*a;}
struct xl
{
double x,y;
xl(double x=,double y=):x(x),y(y){}
void in(){inin(shurux),inin(shuruy);x=shurux,y=shuruy;}
bool op < (const xl &rhs)const {return x==rhs.x?y<rhs.y:x<rhs.x;}
xl op + (const double &rhs)const {return xl(x+rhs,y+rhs);}
xl op - (const double &rhs)const {return xl(x-rhs,y-rhs);}
xl op * (const double &rhs)const {return xl(x*rhs,y*rhs);}
xl op / (const double &rhs)const {return xl(x/rhs,y/rhs);}
xl op + (const xl &rhs)const {return xl(x+rhs.x,y+rhs.y);}
xl op - (const xl &rhs)const {return xl(x-rhs.x,y-rhs.y);}
double angle()const {return atan2(y,x);}
double len()const {return sqrt(f(x)+f(y));}
};
double D_(const xl &a,const xl &b){return a.x*b.x+a.y*b.y;}
double X_(const xl &a,const xl &b){return a.x*b.y-a.y*b.x;}
double dis(const xl &a,const xl &b){return sqrt(f(a.x-b.x)+f(a.y-b.y));}
double dis2(const xl &a,const xl &b){return (a.x-b.x)*(a.x+b.x)+f(a.y-b.y);}
double angle(const xl &a,const xl &b){return acos(D_(a,b)/a.len()/b.len());}
struct LINE
{
xl u,v;double rad;
LINE(xl u=xl(,),xl v=xl(,)):u(u),v(v){}
void js(){rad=(v-u).angle();}
bool op < (const LINE &rhs)const {return rad<rhs.rad;}
};
xl p[],ch[];
LINE a[],b[];
bool onleft(const xl &a,const LINE &l){return dcmp(X_(l.v-l.u,a-l.u))>;}
LINE getline2(xl C,xl D)
{
xl A=p[],B=p[];
// if(D_(B-A,D-C)<0)swap(C,D);
double a=(-A.y+B.y-C.y+D.y),b=(A.x-B.x+C.x-D.x),c=X_(B,A)+X_(D,C);
LINE ret(xl(,-c/b),xl(,(-c-a)/b));
if(!dcmp(b))ret=LINE(xl(-c/a,),xl((-c-b)/a,));
if(!onleft(p[],ret)&&!onleft(p[],ret))swap(ret.u,ret.v);
return ret;
}
LINE getline(xl C,xl D)
{
LINE l=getline2(C,D);
int wocao1=onleft(p[],l)|onleft(p[],l);
int wocao2=onleft(C,l)|onleft(D,l);
if(wocao1^wocao2)return l;
else return getline2(D,C);
}
xl getjd(const LINE &a,const LINE &b)
{
xl u=a.u-b.u,v1=a.v-a.u,v2=b.v-b.u;
double t=X_(v2,u)/X_(v1,v2);
return a.u+v1*t;
}
int n,nn;
bool halfplanej(LINE *l)
{
re(i,,n-)l[i].rad=(l[i].v-l[i].u).angle();
sort(l,l+n);
int ll=,rr=;
xl p[n];LINE b[n];b[]=l[];
re(i,,n-)
{
while(ll<rr&&!onleft(p[rr-],l[i]))rr--;
while(ll<rr&&!onleft(p[ll],l[i]))ll++;
b[++rr]=l[i];
if(!dcmp(X_(b[rr].v-b[rr].u,b[rr-].v-b[rr-].u)))
{
rr--;
if(onleft(l[i].u,b[rr]))b[rr]=l[i];
}
if(ll<rr)p[rr-]=getjd(b[rr-],b[rr]);
}
while(ll<rr&&!onleft(p[rr-],b[ll]))rr--;
if(rr-ll<=)return ;
p[rr]=getjd(b[rr],b[ll]);
re(i,ll,rr)ch[nn++]=p[i];
ch[nn]=ch[];return ;
}
double zongarea,yaoarea;
int main()
{
inin(n);
re(i,,n-)p[i].in();
p[n]=p[];
xl temp=p[]-p[];
re(i,,n-)zongarea+=abs(X_(temp,p[i+]-p[i])),temp=temp+(p[i+]-p[i]);
a[]=LINE(p[],p[]);
re(i,,n-)
a[i]=getline2(p[i+],p[i]);
halfplanej(a);
temp=ch[]-ch[];
re(i,,nn-)
yaoarea+=abs(X_(temp,ch[i+]-ch[i])),temp=temp+(ch[i+]-ch[i]);
printf("%.4f",yaoarea/zongarea);
return ;
}
bzoj4445 小凸想跑步的更多相关文章
- 【BZOJ4445】[Scoi2015]小凸想跑步 半平面交
[BZOJ4445][Scoi2015]小凸想跑步 Description 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸n边形,N个顶点按照逆时针从0-n-l编号.现 ...
- 【BZOJ4445】[SCOI2015]小凸想跑步(半平面交)
[BZOJ4445][SCOI2015]小凸想跑步(半平面交) 题面 BZOJ 洛谷 题解 首先把点给设出来,\(A(x_a,y_a),B(x_b,y_b),C(x_c,y_c),D(x_d,y_d) ...
- 「SCOI2015」小凸想跑步 解题报告
「SCOI2015」小凸想跑步 最开始以为和多边形的重心有关,后来发现多边形的重心没啥好玩的性质 实际上你把面积小于的不等式列出来,发现是一次的,那么就可以半平面交了 Code: #include & ...
- Loj 2008 小凸想跑步
Loj 2008 小凸想跑步 \(S(P,p_0,p_1)<S(P,p_i,p_{i+1})\) 这个约束条件对于 \(P_x,P_y\) 是线性的,即将面积用向量叉积表示,暴力拆开,可得到 \ ...
- loj #2008. 「SCOI2015」小凸想跑步
#2008. 「SCOI2015」小凸想跑步 题目描述 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 n nn 边形,N NN 个顶点按照逆时针从 0∼n−1 0 ...
- 【bzoj4445 scoi2015】小凸想跑步
题目描述 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 nn 边形, nn 个顶点按照逆时针从 00 ∼ n - 1n−1 编号.现在小凸随机站在操场中的某个位置,标 ...
- [SCOI2015]小凸想跑步
题目描述 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 n 边形, nn 个顶点按照逆时针从 0 ∼n−1 编号.现在小凸随机站在操场中的某个位置,标记为p点.将 p ...
- BZOJ 4445 [Scoi2015]小凸想跑步:半平面交
传送门 题意 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 $ n $ 边形,$ n $ 个顶点 $ P_i $ 按照逆时针从 $ 0 $ 至 $ n-1 $ 编号. ...
- BZOJ4445 SCOI2015小凸想跑步(半平面交)
考虑怎样的点满足条件.设其为(xp,yp),则要满足(x0-xp,y0-yp)×(x1-xp,y1-yp)<=(xi-xp,yi-yp)×(xi+1-xp,yi+1-yp)对任意i成立.拆开式子 ...
随机推荐
- 20170907VS中EF模型文件.edmx文件上下级关系丢失问题
状态:A 电脑check in .edmx文件到TFS ,B 电脑vs下载如下文件 vs解决方案中此文件平级显示,原因:ADO.NET 数据模型创建的时候,会在工程文件 .csproj内增加文件层级关 ...
- GUI库之认识Tkinter(一)
一.介绍 Tkinter是Python默认的GUI库,我们经常使用的IDLE就是用Tkinter设计出来的,因此我们在使用的时候直接导入Tkinter模块就好了. 1.特点:可移植性.灵活性高 2.构 ...
- 【BFS宽度优先搜索】
一.求所有顶点到s顶点的最小步数 //BFS宽度优先搜索 #include<iostream> using namespace std; #include<queue> # ...
- 我的DIY作品
工欲善其事必先利其器~呵呵~我自己体会从无到有的乐趣~0~ 从Visio到CAD再到Autodesk,你妹的~只有自己才懂~哎~感谢兄弟朋友们的支持! Visio图: CAD图: Autodesk图:
- PHP 操作 Redis 的手册
转:https://www.cnblogs.com/jackluo/p/5708024.html String 类型操作 string是redis最基本的类型,而且string类型是二进制安全的.意思 ...
- C 表達式及返回值
以下程序的输出结果是__A____. #include<stdio.h> main() { ,j=; printf("%d,%d\n",++i,j--); } A., ...
- C语言数据类型运算法则
整形与整形运算得到的还是整形 printf("%d\n",1/3); //0 printf("%d\n",1+2); //3 整形与浮点型运算得到浮点型数据 p ...
- 下载apk安装包后,调用安装器自动安装apk(适配7.0)
在更新操作时,下载新apk之后,往往需要自动安装新apk,用以下代码即可安装下载在本地的apk文件(apkFile) Intent intent = new Intent(); intent.setA ...
- inner join, left join, right join 和 full join
inner join:理解为“有效连接”,两张表中都有的数据才会显示left join:理解为“有左显示”,比如on a.field=b.field,则显示a表中存在的全部数据及a.b中都有的数据,a ...
- 【LeetCode每天一题】Fibonacci Number(斐波那契数列)
The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such th ...