凸多边形:就是指一个多边形的每一个内角都小于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";
}