【LuoguP4081】[SCOI2015]小凸想跑步

博客围绕凸多边形内三角形面积概率问题展开。题目是求在凸多边形内部选一点,使其与最初输入两点形成的三角形为三角剖分中面积最小的三角形的概率。答案是可行域面积与凸多边形面积之比,求解需快速计算半平面交,最后算出面积相除。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

题意

给你一个凸多边形,求出在其内部选择一个点,这个点与最开始输入的两个点形成的三角形是以该点对凸多边形三角剖分的三角形中面积最小的一个三角形的概率。

Sol

答案就是 可行域面积与该凸多边形面积之比。
通过数学方法列出第一个三角形和其他三角形面积关系的式子,解出来发现都是一个半平面,所以我们要做的就是快速求解半平面交。

把所有要加入的直线用向量表示 , 按照极角排序 ( 用 atan2() ) , 然后依次加入直线。
维护一个双端队列 , 每次加入一条直线时判断最左最右的交点和当前直线的位置关系,如果点在不在加入向量的左侧那么要把最左或最右的直线弹掉。
加入完后还要判一下最右边交点和最左边的向量是否满足左右关系。
求完半平面交之后算个面积除一下就行了。

#include<bits/stdc++.h>
using namespace std;
#define Set(a,b) memset(a,b,sizeof(a))
template<class T>inline void init(T&x){
	x=0;char ch=getchar();bool t=0;
	for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
	if(t) x=-x;return;
}typedef long long ll;
typedef double R;
#define Sqr(a) ((a)*(a))
const R PI=acos(-1),eps=1e-9,INF=1e9;
const int N=2e5+10;
struct point{
	R x,y;
	point(R _x=0.0,R _y=0.0) {x=_x,y=_y;}
	inline R operator *(const point b){return x*b.y-y*b.x;}
	inline point operator *(const R d){return point(x*d,y*d);}
	inline point operator /(const R d){return point(x/d,y/d);}
	inline point operator +(const point b){return point(x+b.x,y+b.y);}
	inline point operator -(const point b){return point(x-b.x,y-b.y);}
	inline void output(){printf("( %lf , %lf )",x,y);return;}
	inline R len(){return sqrt(Sqr(x)+Sqr(y));}
}P[N];
struct line{
	point A,B;R ang;
	line(point _A=point(),point _B=point()){A=_A,B=_B;ang=atan2(B.y,B.x);}
	inline bool operator <(const line b)const{return ang<b.ang;}
}L[N];int cnt=0;
int n;
inline int fcmp(R r){if(r>eps) return 1;else if(r<-eps) return -1;return 0;}
inline bool Left(point A,point B){return fcmp(A*B)>0;}
inline bool isleft(point A,line B){return fcmp(B.B*(A-B.A))>0;}
point Cr[N];R S=0;
inline point Inter(line L1,line L2){return L1.A+L1.B*((L2.B*(L2.A-L1.A))/(L2.B*L1.B));}
inline void HalfPlane(){
	int l,r=1;sort(L+1,L+1+cnt);// 按照斜率(极角)排序
	for(int i=2;i<=cnt;++i) {
		if(fcmp(L[i].ang-L[r].ang)) L[++r]=L[i];
		else if(isleft(L[i].A,L[r])) L[r]=L[i];
	}
	cnt=r,l=r=1;
	for(int i=2;i<=cnt;++i) {// 类似维护凸包
		while(l<r&&!isleft(Cr[r],L[i])) --r;
		while(l<r&&!isleft(Cr[l+1],L[i])) ++l;// 交点必须在内部, 否则上一个向量没有用
		L[++r]=L[i];
		if(l<r) Cr[r]=Inter(L[r],L[r-1]);
	}
	while(l<r&&!isleft(Cr[r],L[l])) --r;
	Cr[l]=Cr[r+1]=Inter(L[l],L[r]);
	R area=0;
	for(int i=l+2;i<=r;++i) area+=(Cr[i-1]-Cr[l])*(Cr[i]-Cr[l]);
	printf("%.4lf\n",area/S);
}
int main()
{
	init(n);S=0;
	for(int i=1;i<=n;++i) {scanf("%lf %lf",&P[i].x,&P[i].y);}
	for(int i=3;i<=n;++i) S+=(P[i-1]-P[1])*(P[i]-P[1]);
	P[n+1]=P[1];
	for(int i=1;i<=n;++i) {
		point Q=P[i+1]-P[i];
		L[++cnt]=line(P[i],Q);
	}
	R kx=P[1].y-P[2].y,ky=P[2].x-P[1].x,re=P[1].x*P[2].y-P[2].x*P[1].y;
	for(int i=2;i<=n;++i){
		R kxx=P[i].y-P[i+1].y,kyy=P[i+1].x-P[i].x,ree=P[i].x*P[i+1].y-P[i+1].x*P[i].y;
		R kY=ky-kyy,kX=kxx-kx,Kre=ree-re;
		if(kY) L[++cnt]=line(point(0,Kre/kY),point(-kY,-kX));
		else if(kX) L[++cnt]=line(point(-Kre/kX,0),point(0,-kX));
	}HalfPlane();
	return 0;
}

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在Web开发与部署过程中,合理设置上传文件的最大大小至关重要。它不仅关乎系统的稳定性和性能,还直接影响用户体验。本文将介绍如何通过修改web.config文件来限制上传文件的最大大小,并探讨其重要性和实现原理。 在Web应用程序中,用户常常需要上传文件,如图片、文档或视频等。为了有效利用服务器资源并避免潜在的安全问题(如DoS攻击),通常需要限制用户上传的单个文件大小。在.NET Framework环境下,这一设置是通过修改web.config文件中的<httpRuntime>元素来实现的。 以下是一个web.config配置片段: maxRequestLength:该属性用于设置HTTP请求中允许的最大POST数据长度(单位为KB)。在示例中,maxRequestLength="8192"表示最大允许的POST数据长度为8192KB,即8MB。如果用户尝试上传超过8MB的文件,系统将拒绝该请求。 useFullyQualifiedRedirectUrl:该属性控制是否在重定向时使用完全限定的URL。此设置与上传文件大小限制无直接关联,但在某些场景下可能间接影响处理流程。 executionTimeout:表示一个HTTP请求的执行超时时间(单位为秒)。默认值为110秒。如果请求处理时间超过该值,会触发超时异常。 versionHeader:指定响应中包含的版本头。 提高安全性:限制文件大小可以防止恶意用户上传过大的文件,消耗服务器资源,引发DoS攻击。 优化性能:较小的文件更容易处理,有助于减少服务器负载,提高整体性能。 改善用户体验:合理设置文件大小限制,可让用户了解哪些文件是可接受的,减少因上传失败而造成的不便。 打开web.config文件:使用文本编辑器打开项目根目录下的we
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值