P3744 李彬的几何

 

凸多边形:就是指一个多边形的每一个内角都小于180180度的的多边形

凹多边形:就是指至少有一个内角大于180180度的多边形

让一个凸多边形变成一个凹多边形:

随便取一点,固定两个邻点,把这个点网多边形内部拖,这样的话多边形就完成了一次转变,而这里的一点是可以更换的,所对应的移动距离就是题目中要求的d值。

众所周知,垂线段最短,也就是一点到相邻两点所连成直线的距离

我们可以先用勾股定理求出三边之长

再用海伦公式求面积:

最后的结果需要除以2。

上代码:

#include<bits/stdc++.h>
#define lmw ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define int long long
using namespace std;
#define x first
#define y second
typedef pair<double,double> pdd;
const int N=1000010;
int n;
pdd q[N];
int s[N];
bool used[N];
double get_dist(pdd a,pdd b){
	double dx=a.x-b.x;
	double dy=a.y-b.y;
	return sqrt(dx*dx+dy*dy);
}
pdd operator-(pdd a,pdd b){
	return {a.x-b.x,a.y-b.y};
}
double cross(pdd a,pdd b){
	return a.x*b.y-a.y*b.x;
}
double area(pdd a ,pdd b,pdd c){
	pdd A=pdd(b.x-a.x,b.y-a.y);
	pdd B=pdd(c.x-a.x,c.y-a.y); 
	return cross(b-a,c-a);
}
double andrew(){
	sort(q,q+n);
	int top=0.0;
	for(int i=0;i<n;i++){
		while(top>=2&&area(q[s[top-1]],q[s[top]],q[i])>=0){
			used[s[top--]]=0;
		}
		s[++top]=i;
		used[i]=1;
	}
	used[0]=0;
	for(int i=n-1;i>=0;i--){
		if(used[i]) continue;
		while(top>=2&&area(q[s[top-1]],q[s[top]],q[i])>=0) top--;
		s[++top]=i;
	}
	double res=0.0;
	for(int i=2;i<=top;i++){
		res+=get_dist(q[s[i-1]],q[s[i]]);
	}
	return res;
}
signed main(){
    lmw;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>q[i].x>>q[i].y;
	}
	double a,b,c,s,e,h,minl=0x3f3f3f3;
	for(int i=0;i<n;i++){
		a=get_dist(q[(i+1)%n],q[(i+2)%n]);
		b=get_dist(q[i],q[(i+2)%n]);
		c=get_dist(q[i],q[(i+1)%n]);
		e=0.5*(a+b+c);
		s=sqrt(e*(e-a)*(e-b)*(e-c));
		h=s/b;
		minl=min(minl,h);
	}
	cout<<fixed<<setprecision(10)<<minl<<"\n";
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值