记录编号 |
375906 |
评测结果 |
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA |
题目名称 |
大灾变 |
最终得分 |
100 |
用户昵称 |
New World |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
5.008 s |
提交时间 |
2017-02-26 10:17:22 |
内存使用 |
72.41 MiB |
显示代码纯文本
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define Inf 2e100
#define eps 1e-12
const int maxn=1050000;
struct Point{
double x,y;
Point(double xx=0,double yy=0){x=xx;y=yy;}
void input(){scanf("%lf%lf",&x,&y);}
void output(){printf("<<%.3lf %.3lf>>",x,y);}
};
typedef Point Vector;
int dcmp(double x)
{return fabs(x)<eps ? 0 : x>0 ? 1 :-1;}
bool operator == (Vector A,double x)
{return dcmp(A.x-x)==0 && dcmp(A.y-x)==0;}
bool operator < (Point A,Point B)
{return A.x!=B.x ? A.x<B.x : A.y<B.y;}
Vector operator - (Point A,Point B)
{return Vector(A.x-B.x,A.y-B.y);}
Point operator + (Point A,Vector B)
{return Point(A.x+B.x,A.y+B.y);}
Vector operator * (Vector A,double x)
{return Vector(A.x*x,A.y*x);}
double Cross(Vector A,Vector B)
{return A.x*B.y-A.y*B.x;}
double Dot(Vector A,Vector B)
{return A.x*B.x+A.y*B.y;}
double Length(Vector A)
{return sqrt(Dot(A,A));}
struct Line{
Point P;Vector v;
double ang;
Line(){};
Line(Point A,Vector B){
P=A;v=B;
ang=atan2(v.y,v.x);
}
bool operator < (const Line & A)const{
return ang<A.ang;
}
};
bool OnLeft(Line L,Point P)
{return dcmp(Cross(L.v,P-L.P))>=0;}
Point LineInterSection(Line A,Line B){
if(B.v==0 && A.v==0)return Point(Inf,Inf);
if(B.v==0){
if(dcmp(Cross(A.v,B.P-A.P))==0)return B.P;
}
if(A.v==0){
if(dcmp(Cross(B.v,A.P-B.P))==0)return A.P;
}
Vector u=A.P-B.P;
double t=Cross(B.v,u)/Cross(A.v,B.v);
return A.P+A.v*t;
}
int HalfPlaneInterSection(Line *L,int n,Point *poly){
sort(L,L+n);
Point *p=new Point[n];
Line *q=new Line[n];
int head,tail;
q[head=tail=0]=L[0];
for(int i=1;i<n;i++){
while(head<tail && !OnLeft(L[i],p[tail-1]))tail--;
while(head<tail && !OnLeft(L[i],p[head ]))head++;
q[++tail]=L[i];
if(dcmp(Cross(q[tail].v,q[tail-1].v))==0){
tail--;
if(OnLeft(q[tail],L[i].P))q[tail]=L[i];
}
p[tail-1]=LineInterSection(q[tail],q[tail-1]);
}
while(head<tail && !OnLeft(q[head],p[tail-1]))tail--;
if(tail-head<=1)return 0;
p[tail]=LineInterSection(q[tail],q[head]);
int m=0;
for(int i=head;i<=tail;i++)poly[++m]=p[i];
return m;
}
int n,cnt;
Point p[maxn],poly[maxn];
Line L[maxn];
void Init();
int main(){
freopen("cataclysm.in","r",stdin);
freopen("cataclysm.out","w",stdout);
Init();
return 0;
}
void Init(){
scanf("%d",&n);
for(int i=1;i<=n;i++)p[i].input();
sort(p+1,p+n+1);
for(int i=1;i<n;i++)
L[cnt++]=Line(p[i],p[i+1]-p[i]);
L[cnt++]=Line(p[n],Vector(0,1));
L[cnt++]=Line(p[1],Vector(0,-1));
L[cnt++]=Line(Point(0,Inf),Vector(-1,0));
int m=HalfPlaneInterSection(L,cnt,poly);
Point flyer;flyer.y=Inf;
for(int i=1;i<=m;i++)
if(dcmp(poly[i].y-flyer.y)<0)
flyer=poly[i];
int i=1,j=1;m--;
//for(int i=1;i<=m;i++)poly[i].output();
Point Fire;double ans=Inf;
//从山脉对应下凸壳
while(p[i+1].x<poly[1].x)i++;
for(;i<=n;i++){
if(p[i].x>poly[m].x)break;
while(poly[j+1].x<p[i].x)j++;
Line l1=Line(p[i],Vector(0,1));
Line l2=Line(poly[j],poly[j+1]-poly[j]);
Point Inter=LineInterSection(l1,l2);
//Inter.output();
double len=Length(Inter-p[i]);
if(dcmp(len-ans)==-1){
Fire=Inter;ans=len;
}
}
//从下凸壳对应山脉
i=1;j=1;
while(p[i+1].x<poly[1].x)i++;
for(;j<=m;j++){
if(p[i].x>poly[m].x)break;
while(p[i+1].x<poly[j].x)i++;
Line l1=Line(poly[j],Vector(0,-1));
Line l2=Line(p[i],p[i+1]-p[i]);
Point Inter=LineInterSection(l1,l2);
double len=Length(Inter-poly[j]);
if(dcmp(len-ans)==-1){
Fire=poly[j];ans=len;
}
}
printf("%.2lf %.2lf\n",Fire.x,Fire.y);
printf("%.2lf %.2lf\n",flyer.x,flyer.y);
//printf("%d\n",m);
}