P2600 [ZJOI2008] Watchtower

Title Description

Committed to building a national model of harmonious hamlet H village chief dadzhi, decided to build a watchtower in the village, to strengthen law and order in the village.

We will abstract H village is a one-dimensional profile. As shown below

img

We can use the top of a hill contour polylines (x1, y1), (x2, y2), .... (Xn, yn) to describe the shape of the H village, where x1 <x2 <... <xn. Watchtowers can be built in [x1, xn] anywhere in between, but it must meet can be seen anywhere in the village of H from the top of the observation tower. Highly visible watchtower built in different locations, the need to build is different. To save money, dadzhi village wants to build a tower height as small as possible.

You are to write a program to help dadzhi village calculating the minimum height of the tower.

Input Format

The first line of the input file comprises a tower.in integer n, the number of nodes polyline outline. Next, a first row of n integers and x1 ~ xn. The third row of n integers and y1 ~ yn.

Output Format

Tower.out output file contains only a real number, the minimum height of the column, accurate to three decimal places.

Sample input and output

Input # 1

6

1 2 4 5 6 7

1 2 2 4 2 1

Output # 1

1.000

Description / Tips

Data for 60%, N ≤ 60;

Data for 100%, N ≤ 300, the coordinate input absolute value is not more than 106, consider the real attention error caused.

Half-plane cross exercises, note that there is no judgment at the right time, to think clearly or not on-line

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const int N = 350;
const double eps = 1e-7;
int n , head , tail;
struct point{
    double x , y;
    point(double X = 0.0 , double Y = 0.0): x(X) , y(Y) {}
    bool operator < (const point &A) const { return x < A.x; }
    friend point operator - (point A , point B) { return point(A.x - B.x , A.y - B.y); }
    friend point operator * (point A , double B) {return point(A.x * B , A.y * B); }
    friend point operator + (point A , point B) { return point(A.x + B.x , A.y + B.y); }
} a[N] , p[N];

struct Line{
    point v , p;
    double an;
    Line(point V = point(0,0), point P = point(0,0)) : v(V) , p(P) { an = 0.0;}
    bool operator < (const Line A) const { return an < A.an; }
} l[N] , sta[N] , li[N];
inline int dcmp(double A) { return fabs(A) < eps ? 0 : (A < eps ? -1 : 1); }
inline double accross(point A , point B) { return A.x * B.y - A.y * B.x; }
inline bool onright(point A , Line B) { return dcmp(accross(A - B.p , B.v)) > 0; }
inline point meetline(Line A , Line B)
{
    if(dcmp(accross(A.v , B.v)) == 0) return (point){0 , 0};
    point k = A.p - B.p;
    return A.p + A.v * (accross(B.v , k) / accross(A.v , B.v));
}

int Get_ans(int n)
{
    sort(l + 1 , l + 1 + n); sta[head = tail = 1] = l[1];
    for(int i = 2 ; i <= n ; ++i)
    {
        while(head < tail && onright(p[tail-1] , l[i])) tail--;
        while(head < tail && onright(p[head] , l[i])) head++;
        sta[++tail] = l[i];
        if(dcmp(accross(sta[tail].v , sta[tail-1].v)) == 0)
        {
            tail--;
            if(onright(sta[tail].p , l[i])) sta[tail] = l[i];
        }
        if(head < tail) p[tail-1] = meetline(sta[tail] , sta[tail-1]);
    }
    while(head < tail && onright(p[tail-1] , sta[head])) tail--;
    for(int i = head ; i <= tail ; ++i) p[i-head+1] = p[i] , sta[i-head+1] = sta[i]; 
    return tail - head;
}

double calc(point p , point a , point b)
{
    double K = (b.y - a.y) / (b.x - a.x);
    double B = a.y - K * a.x;
    return fabs(p.x * K + B - p.y);
}

int main()
{
    scanf("%d" , &n);
    for(int i = 1 ; i <= n ; ++i) scanf("%lf" , &a[i].x);
    for(int i = 1 ; i <= n ; ++i) scanf("%lf" , &a[i].y);
    sort(a + 1 , a + 1 + n);
    for(int i = 1 ; i < n ; ++i) l[i].v = a[i+1] - a[i] , l[i].p = a[i] , l[i].an = atan2(l[i].v.y , l[i].v.x) , li[i] = l[i];
    int cnt = Get_ans(n - 1);
    // cout << cnt << endl;
    int l = 1 , r = 1; double ans = 1e15;
    while(l <= cnt && r <= n)
    {
        if(p[l].x < a[r].x)
        ans = min(ans , p[l].y - meetline(li[r-1] , Line(point(0,1) , p[l])).y) , l++;
        else
        ans = min(ans , meetline(sta[l] , Line(point(0,1) , a[r])).y - a[r].y) , r++;
    }
    while(l <= cnt) ans = min(ans , p[l].y - meetline(li[r-1] , Line(point(0,1) , p[l])).y) , l++;
    while(r <=  n)  ans = min(ans , meetline(sta[l] , Line(point(0,1) , a[r])).y - a[r].y) , r++;
    printf("%.3f" , ans);
    return 0;
}
/*
4
10 20 49 59
0 10 10 0
*/

Guess you like

Origin www.cnblogs.com/R-Q-R-Q/p/12147886.html