应该是精度问题
WA了大概15次
全都在第一个点
但是我调不出来
球球大佬帮帮我
今天之内给关注
#include <iostream>
#include <cmath>
#include <algorithm>
#include <bitset>
#include <iomanip>
#include <vector>
#define db double
#define MAXN 50001
using namespace std;
#define ri register int
inline void syncwithme(){
ios::sync_with_stdio(false);
cin.tie(NULL),cout.tie(NULL);
}
#define eps 1e-7
inline db chk(db x){ return fabs(x)<eps?0:x; }
struct victor{
db x,y;
victor() { }
victor(db x,db y) : x(chk(x)),y(chk(y)){ }
inline victor operator +(const victor &a){ return victor(x+a.x,y+a.y); } //加
inline victor operator -(const victor &a){ return victor(x-a.x,y-a.y); } //减
inline db operator *(const victor &a){ return x*a.x+y*a.y; } //点积
inline db operator ^(const victor &a){ return x*a.y-y*a.x; } //叉积的值
inline void operator +=(const victor &a){ x+=a.x,y+=a.y; }
inline void operator -=(const victor &a){ x-=a.x,y-=a.y; }
inline bool operator ==(const victor &a){ return x==a.x&&y==a.y; } //判断两个向量相等
inline bool iszero(){ return (!x)&&(!y); } //判断是否是零向量
inline db sqr(){ return x*x+y*y; }
};
inline bool cmp(victor a,victor b){ return a.x!=b.x?a.x<b.x:a.y<b.y; }
victor pt[MAXN];
int n,sta[MAXN<<1],top;
bitset<MAXN> vis;
inline void Andrew(){
sort(pt+1,pt+n+1,cmp);
sta[++top]=1;
for(ri i=2;i<=n;i++){
while((top^1)&&((pt[sta[top-1]]-pt[sta[top]])^(pt[i]-pt[sta[top]]))>=0)
vis[sta[top--]]=0;
vis[i]=1,sta[++top]=i;
} ri t=top;
for(ri i=n-1;i>=1;i--){
if(vis[i]) continue;
while((top^t)&&((pt[sta[top-1]]-pt[sta[top]])^(pt[i]-pt[sta[top]]))>=0)
vis[sta[top--]]=0;
vis[i]=1,sta[++top]=i;
}
}
#define S(a,b,c) chk(abs((pt[a]-pt[b])^(pt[c]-pt[b])))
#define L(a,b,c) chk((pt[a]-pt[b])*(pt[c]-pt[b]))
int st; db ans=1e10;
victor p[4];
inline void Spinning(){
register db t1,t2,t3;
ri p1(3),p2(2),p3(2); //p1:上方 p2:左边 p3:右边
for(ri i=1;i<=top-1;i++){
while(S(sta[i],sta[i+1],sta[p1])<=S(sta[i],sta[i+1],sta[p1%top+1]))
p1=p1%top+1;
while(L(sta[i],sta[i+1],sta[p3])>=L(sta[i],sta[i+1],sta[p3%top+1]))
p3=p3%top+1;
if(i==1) p2=p3;
while(L(sta[i],sta[i+1],sta[p2])<=L(sta[i],sta[i+1],sta[p2%top+1]))
p2=p2%top+1;
//printf("p1=%d p2=%d p3=%d On Line %d\n",p1,p2,p3,i);
t1=S(sta[i],sta[i+1],sta[p1]),
t2=L(sta[i],sta[i+1],sta[p2])+L(sta[i+1],sta[i],sta[p3]),
t3=L(sta[i],sta[i+1],sta[i]); t2-=t3;
if(ans>chk(t1*t2/t3)){
ans=chk(t1*t2/t3);
/*
3
0 1
0 1.00001
20000 0
*/
register db k1,b1,k2,b2,x,y;
if(pt[sta[i+1]].x==pt[sta[i]].x){
p[0]=victor(pt[sta[i]].x,pt[sta[i]].y);
p[1]=victor(pt[sta[i]].x,pt[sta[i+1]].y);
p[2]=victor(pt[sta[p3]].x,pt[sta[i+1]].y);
p[3]=victor(pt[sta[p3]].x,pt[sta[i]].y);
} else if(pt[sta[i+1]].y==pt[sta[i]].y){
p[0]=victor(pt[sta[i]].x,pt[sta[i]].y);
p[1]=victor(pt[sta[i+1]].x,pt[sta[i]].y);
p[2]=victor(pt[sta[i+1]].x,pt[sta[p3]].y);
p[3]=victor(pt[sta[i]].x,pt[sta[p3]].y);
} else{
k1=chk(chk((pt[sta[i+1]].y-pt[sta[i]].y))/chk((pt[sta[i+1]].x-pt[sta[i]].x)));
b1=chk(pt[sta[i]].y-k1*pt[sta[i]].x);
// printf("k1 = %.5lf , b1 = %.5lf\n",k1,b1);
//当前旋转的底边的斜率和截距
k2=chk(-1.0/k1);
b2=chk(pt[sta[p2]].y-k2*pt[sta[p2]].x);
// printf("k2 = %.5lf , b2 = %.5lf\n",k2,b2);
//垂直于底边的左直线
p[0]=victor((b2-b1)/(k1-k2),(k1*b2-k2*b1)/(k1-k2)); //左下的顶点
b2=chk(pt[sta[p3]].y-k2*pt[sta[p3]].x);; //最右边垂直边的截距
p[1]=victor((b2-b1)/(k1-k2),(k1*b2-k2*b1)/(k1-k2)); //右下的顶点
b1=chk(pt[sta[p1]].y-k1*pt[sta[p1]].x); //最上面平行边的截距
p[2]=victor((b2-b1)/(k1-k2),(k1*b2-k2*b1)/(k1-k2)); //右上的顶点
b2=chk(pt[sta[p2]].y-k2*pt[sta[p2]].x);
p[3]=victor((b2-b1)/(k1-k2),(k1*b2-k2*b1)/(k1-k2)); //左上的顶点
}
}
}
}
int main()
{
syncwithme();
cin>>n; db x,y;
for(ri i=1;i<=n;i++)
cin>>x>>y,pt[i]=victor(x,y);
Andrew();
Spinning();
for(ri i=0;i<=3;i++)
if(p[i].y<p[st].y||(p[i].y==p[st].y&&p[i].x<p[st].x)) st=i;
cout<<fixed<<setprecision(5)<<ans<<endl;
//cout<<"st="<<st<<endl;
for(ri i=0;i<=3;i++)
cout<<p[(st+i)%4].x<<" "<<p[(st+i)%4].y<<endl;
return 0;
}
计算几何真好玩
这两天一道题都不卡
我回去打主席树了