jzoj1896. Cataclysm

Title description

Description After
  the world of Azeroth experienced an unprecedented earthquake, the land and ocean were completely torn apart, and the old continent was incomplete. The inhabitants of the Alliance and the tribes of various races were forced to leave their homes where they lived for generations to find new living spaces. Peaks have now risen from the originally flat land, and the humans of Stormwind have begun to rebuild their homes in the Elwynn Mountains. They decided to build a watchtower and a magical floating island among the mountains, so that the entire view of the Irvine Mountains could be overlooked on the watchtower and the floating island.
  The Alvin Mountains are described as a polyline. Given the coordinates of each point (both the horizontal and vertical coordinates are not less than 0), the polyline of the mountains is the polyline of the mountains when they are connected in order from small to large according to the horizontal coordinate. The abscissas of all points on the polyline are different. If the connection between a location and any point of the mountain is not blocked (but it can be tangent to the ground), then it can be said that the entire Elvin Mountains can be seen at this point. The body of the watchtower will not block the line of sight, and the watchtower and the floating island can be built at the same location. In order to save construction materials, the height of the watchtower body must be as small as possible, that is, the distance from the top of the tower to the bottom of the tower is as small as possible, and the watchtower can be built on a hillside. Due to climatic factors, the floating island should be built at the lowest possible altitude (or even on the ground), and the sea level is 0. If multiple locations meet the conditions, the one with the smallest abscissa is selected. The abscissa range of the observation tower and the floating island should be within the abscissa range of the Irvine Mountains.
  Given the Alvin Mountains, please find the location of the watchtower and the floating island.

Input
  line 1, an integer N, represents the number of vertices of the polyline describing the Alvin Mountains.
  Line 2-N+1, each line contains two integers, xi, yi represent the coordinates of points on the polyline.

In the
  first line of Output , two floating-point numbers x1, y1 with 2 decimal places, represent the coordinates of the top of the watchtower.
  In the second line, two floating-point numbers x2, y2 with 2 decimal places, represent the coordinates of the floating island.

Sample Input
6
2 2
6 1
8 6
10 3
16 5
20 2

Sample Output
8.00 11.00
9.54 9.85

Data Constraint

Hint
[Sample description] The vertices of the Alvin Mountains described in the sample are connected in the order of the abscissa, as shown in the following figure: The
Insert picture description here
watchtower should be built at the peak (8,6), and the top of the tower is ( 8,11), the height is 5, at this time the height of the watchtower is the smallest.      
Insert picture description here
The floating island is established at (9.54, 9.85), with the lowest altitude.
Insert picture description here

[Data scale]
  40% of data 2<=N<=10
  100% of data 2<=N<=1 000 000;
0<=xi,yi<=5 000 000

answer

Half-plane intersecting questions
and there is only a lower convex hull, so there is no need to queue

The floating island is the lowest point of the convex hull
. The x of the watchtower can only be a certain x of the lower convex hull/origin
plus two points at the beginning and the end of the convex hull. After sorting, the search is monotonous, and the middle of the adjacent point is found each time. Other points to intersect

However
, the point of this question is time/space/precision.
Insert picture description here
I feel that the
Insert picture description here
Insert picture description here
above two are the same program.

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define cj(a,b,c) ((c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y))
#define abs(x) ((x)>0?(x):-(x))
#define max(a,b) (a>b?a:b)
#define pi 3.14159265358979323846
#define E 0.0000001
using namespace std;

struct P{
    
    
	double x,y;
	P (double _x=0,double _y=0) {
    
    x=_x,y=_y;}
} O=P(0,0),p[100001],Jd,A[1000001];
struct P2{
    
    
	double x,y;
	int type;
} b[2000001];
struct L{
    
    
	P s1,s2;
	float xl;
	L (double _x1=0,double _y1=0,double _x2=0,double _y2=0) {
    
    s1.x=_x1,s1.y=_y1,s2.x=_x2,s2.y=_y2;}
} a[1000001],l1,l2; //s1-->s2
int N,n,i,j,k,l,t,tot,ls1,ls2;
double ans1,ans1x,ans1y,ans2,ans2x,ans2y,s;
long double s1,s2,S;
char ch[16000001];
char *Ch=ch;

int getint()
{
    
    
	int x=0;
	
	while (*Ch<'0'  || *Ch>'9' ) *++Ch;
	while (*Ch>='0' && *Ch<='9') x=x*10+(*Ch-'0'),*++Ch;
	
	return x;
}

//long double cj(P a,P b,P c)
//{
    
    
//	long double s=(c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);
//	
//	if (abs(s)<=E)
//	return 0;
//	else
//	return s;
//}

bool cmp(L a,L b)
{
    
    
	return abs(a.xl-b.xl)>E && a.xl<b.xl || abs(a.xl-b.xl)<=E && cj(a.s1,a.s2,b.s2)<0;
}
bool Cmp(P2 a,P2 b)
{
    
    
	return a.x<b.x;
}
bool CMP(P a,P b)
{
    
    
	return a.x<b.x;
}

P jd(L a,L b)
{
    
    
	s1=cj(a.s1,b.s1,a.s2),s2=cj(a.s1,a.s2,b.s2);
	S=s1/(s1+s2);
	
	return P(b.s1.x+(b.s2.x-b.s1.x)*S,b.s1.y+(b.s2.y-b.s1.y)*S);
}

float xl(L a)
{
    
    
	float x=a.s2.x-a.s1.x,y=a.s2.y-a.s1.y;
	
	if (abs(y)<=E)
	{
    
    
		if (x>0)
		return 0;
		else
		return pi;
	}
	if (abs(x)<=E)
	{
    
    
		if (y>0)
		return pi/2;
		else
		return pi*3/2;
	}
	
	if (x>0 && y>0)
	return atan(y/x);
	if (x<0 && y>0)
	return atan(y/x)+pi;
	if (x<0 && y<0)
	return atan(y/x)+pi;
	if (x>0 && y<0)
	return atan(y/x)+pi+pi;
}

int main()
{
    
    
//	freopen("cataclysm38.in","r",stdin);
//	freopen("S8_2_3.in","r",stdin);
	
	fread(ch,1,16000001,stdin);
	
	n=getint();
	fo(i,1,n)
	A[i].x=getint(),A[i].y=getint();
	sort(A+1,A+n+1,CMP);
	
	N=0;
	fo(i,2,n)
	{
    
    
		++N;
		a[N]=L(A[i].x,A[i].y,A[i-1].x,A[i-1].y);
		a[N].xl=xl(a[N]);
	}
	
	sort(a+1,a+N+1,cmp);
	
	j=0;
	fo(i,1,N)
	if (i==1 || abs(a[i].xl-a[i-1].xl)>E)
	a[++j]=a[i];
	N=j;
	
	t=1;
	fo(i,2,N)
	{
    
    
		while (t>1 && cj(a[i].s1,a[i].s2,p[t-1])<=0)
		--t;
		
		a[++t]=a[i];
		p[t-1]=jd(a[t-1],a[t]);
	}
	
	tot=0;
	fo(i,1,n)
	{
    
    
		++tot;
		b[tot].x=A[i].x;
		b[tot].y=A[i].y;
		b[tot].type=0;
	}
	fo(i,1,t-1)
	{
    
    
		++tot;
		b[tot].x=p[i].x;
		b[tot].y=p[i].y;
		b[tot].type=1;
	}
	
	if (t==1 || p[1].x>A[1].x)
	{
    
    
		++tot;
		l1=L(A[1].x,A[1].y,A[1].x,233333333333333ll);
		Jd=jd(l1,a[1]);
		b[tot].x=Jd.x;
		b[tot].y=Jd.y;
		b[tot].type=1;
	}
	if (t==1 || p[t-1].x<A[n].x)
	{
    
    
		++tot;
		l1=L(A[n].x,A[n].y,A[n].x,233333333333333ll);
		Jd=jd(l1,a[t]);
		b[tot].x=Jd.x;
		b[tot].y=Jd.y;
		b[tot].type=1;
	}
	
	sort(b+1,b+tot+1,Cmp);
	
	ans1=233333333333333ll;
	ans2=233333333333333ll;
	
	ls1=0;
	ls2=0;
	fo(i,1,tot)
	{
    
    
		if (i<tot && abs(b[i].x-b[i+1].x)<=E)
		{
    
    
			s=abs(b[i].y-b[i+1].y);
			if (abs(s-ans1)>E && s<ans1 || abs(s-ans1)<=E && b[i].x<ans1x)
			{
    
    
				ans1=s;
				ans1x=b[i].x;
				ans1y=max(b[i].y,b[i+1].y);
			}
		}
		
		if (!b[i].type)
		{
    
    
			if (ls1)
			{
    
    
				fo(j,ls1+1,i-1)
				{
    
    
//					l1=L(b[j].x,-233333333333333ll,b[j].x,b[j].y);
//					l2=L(b[ls1].x,b[ls1].y,b[i].x,b[i].y);
//					
//					Jd=jd(l1,l2);
					
					Jd.x=b[j].x;
					Jd.y=b[ls1].y+(b[j].x-b[ls1].x)/(b[i].x-b[ls1].x)*(b[i].y-b[ls1].y);
					
					s=b[j].y-Jd.y;
					if (abs(s-ans1)>E && s<ans1 || abs(s-ans1)<=E && b[j].x<ans1x)
					{
    
    
						ans1=s;
						ans1x=b[j].x;
						ans1y=b[j].y;
					}
				}
			}
			ls1=i;
		}
		else
		{
    
    
			if (ls2)
			{
    
    
				fo(j,ls2+1,i-1)
				{
    
    
//					l1=L(b[j].x,233333333333333ll,b[j].x,b[j].y);
//					l2=L(b[ls2].x,b[ls2].y,b[i].x,b[i].y);
//					
//					Jd=jd(l1,l2);
					
					Jd.x=b[j].x;
					Jd.y=b[ls2].y+(b[j].x-b[ls2].x)/(b[i].x-b[ls2].x)*(b[i].y-b[ls2].y);
					
					s=Jd.y-b[j].y;
					if (abs(s-ans1)>E && s<ans1 || abs(s-ans1)<=E && Jd.x<ans1x)
					{
    
    
						ans1=s;
						ans1x=Jd.x;
						ans1y=Jd.y;
					}
				}
			}
			ls2=i;
			
			s=b[i].y;
			if (abs(s-ans2)>E && s<ans2 || abs(s-ans2)<=E && b[i].x<ans2x)
			{
    
    
				ans2=s;
				ans2x=b[i].x;
				ans2y=b[i].y;
			}
		}
	}
	
	if (abs(ans1x)<=E) ans1x=0;
	if (abs(ans1y)<=E) ans1y=0;
	if (abs(ans2x)<=E) ans2x=0;
	if (abs(ans2y)<=E) ans2y=0;
	
	printf("%0.2lf %0.2lf\n",ans1x,ans1y);
	printf("%0.2lf %0.2lf\n",ans2x,ans2y);
}

Guess you like

Origin blog.csdn.net/gmh77/article/details/98318501