## Editorial for Hang động

Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này

#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <climits>
#include <cstdlib>
#include <ctime>
#include <memory.h>
#include <cassert>
#include <climits>
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define REP(i, a, b) for(int i = (a); i <=(b); i++)
#define FORD(i, a, b) for(int i = (a); i > (b); i--)
#define REPD(i, a, b) for(int i = (a); i >=(b); i--)
#define TR(it, a) for(typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define RESET(a, v) memset((a), (v), sizeof((a)))
#define SZ(a) (int((a).size()))
#define ALL(a) (a).begin(), (a).end()
#define PB push_back
#define MP make_pair
#define LL long long
#define LD long double
#define II pair<int, int>
#define X first
#define Y second
#define VI vector<int>
const int N = 5050;
const double EPS = 1e-9;
using namespace std;

typedef pair<double, double> point;
typedef pair<double, double> line;

bool eq(const double &a, const double &b)
{return fabs(a - b) < EPS;}
bool eqX(const point &a, const point &b)
{return eq(a.X, b.X);}

line makeLine(point P, point Q) {
line tmp;
tmp.X = (P.Y - Q.Y) / (P.X - Q.X);
tmp.Y = P.Y - tmp.X * P.X;
return tmp;
}

double xIntercept(line d1, line d2)
{return (d2.Y - d1.Y) / (d1.X - d2.X);}
double yIntercept(line d1, line d2){
double x = xIntercept(d1, d2);
return d1.X * x + d1.Y;
}

bool bad(line a, line b, line c)
{return xIntercept(a, b) > EPS + xIntercept(b, c);}
bool cmp(const point &a, const point &b) {
return !eq(a.X, b.X) ? a.X < b.X : a.Y > b.Y;
}
int n;
point a[N];

int main() {
ios :: sync_with_stdio(0); cin.tie(0);
cin >> n;
FOR(i, 0, n) cin >> a[i].X >> a[i].Y;
vector<line> lines, hull;
FOR(i, 1, n) lines.PB(makeLine(a[i - 1], a[i]));
sort(ALL(lines), cmp);
lines.resize(unique(ALL(lines), eqX) - lines.begin());
#define nn SZ(hull)
FOR(i, 0, SZ(lines)) {
while (nn > 1 && bad(hull[nn - 2], hull[nn - 1], lines[i])) hull.pop_back();
hull.PB(lines[i]);
}
double ans = 1e7;
FOR(i, 1, nn)
ans = min(ans, yIntercept(hull[i - 1], hull[i]));
cout << setprecision(2) << fixed << ans;
return 0;
}


{$R+,Q+,N+} PROGRAM NKSPILJA; CONST FINP=''; FOUT=''; oo=1000000; maxn=5000; max=1000000; esp=0.005; VAR x,y:array[1..maxn] of double; n:longint; kq:double; procedure readInput; var f:text; i:integer; begin assign(f,FINP); reset(f); read(f,n); for i:=1 to n do read(f,x[i],y[i]); close(f); end; procedure writeOutput; var f:text; begin assign(f,FOUT); rewrite(f); writeln(f,kq:0:2); close(f); end; function ok(y0:double):boolean; var l,r,x0:double; i:longint; begin l:=0; r:=max; for i:=1 to n-1 do if y[i]=y[i+1] then begin if y0<y[i] then begin l:=oo; r:=0; end; end else if y[i]>y[i+1] then begin x0:=(x[i]*y[i+1]-y[i]*x[i+1]-(x[i]-x[i+1])*y0)/(y[i+1]-y[i]); if x0>l then l:=x0; end else if y[i]<y[i+1] then begin x0:=(x[i]*y[i+1]-y[i]*x[i+1]-(x[i]-x[i+1])*y0)/(y[i+1]-y[i]); if x0<r then r:=x0; end; if l<r then ok:=true else ok:=false; end; procedure chia(y1,y2:double); var mid:double; begin mid:=(y1+y2)/2; if ok(mid) then begin if mid-y1<esp then begin kq:=mid; writeOutput; halt; end; chia(y1,mid); end else begin if y2-mid<esp then begin kq:=mid; writeOutput; halt; end; chia(mid,y2); end; end; BEGIN readInput; chia(0,oo); END.  #### Code mẫu của hieult #include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <bitset> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iomanip> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef long double ld; //typedef double ld; typedef unsigned int ui; typedef unsigned long long ull; #define Rep(i,n) for(__typeof(n) i = 0; i < (n); ++i) #define Repd(i,n) for(__typeof(n) i = (n)-1; i >= 0; --i) #define For(i,a,b) for(__typeof(b) i = (a); i <= (b); ++i) #define Ford(i,a,b) for(__typeof(a) i = (a); i >= (b); --i) #define Fit(i,v) for(__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++i) #define Fitd(i,v) for(__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++i) #define mp make_pair #define pb push_back #define fi first #define se second #define sz(a) ((int)(a).size()) #define all(a) (a).begin(), (a).end() #define ms(a,x) memset(a, x, sizeof(a)) #define nl puts("") #define sp printf(" ") #define ok puts("ok") //#include <conio.h> template<class F, class T> T convert(F a, int p = -1) { stringstream ss; if (p >= 0) ss << fixed << setprecision(p); ss << a; T r; ss >> r; return r; } template<class T> void db(T a, int p = -1) { if (p >= 0) cout << fixed << setprecision(p); cout << a << " "; } template<class T> T gcd(T a, T b) { T r; while (b != 0) { r = a % b; a = b; b = r; } return a; } template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; } template<class T> T sqr(T x) { return x * x; } template<class T> T cube(T x) { return x * x * x; } template<class T> struct Triple { T x, y, z; Triple() {} Triple(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {} }; template<class T> Triple<T> euclid(T a, T b) { if (b == 0) return Triple<T>(1, 0, a); Triple<T> r = euclid(b, a % b); return Triple<T>(r.y, r.x - a / b * r.y, r.z); } template<class T> int getbit(T s, int i) { return (s >> i) & 1; } template<class T> T onbit(T s, int i) { return s | (T(1) << i); } template<class T> T offbit(T s, int i) { return s & (~(T(1) << i)); } template<class T> int cntbit(T s) { return s == 0 ? 0 : cntbit(s >> 1) + (s & 1); } const int bfsz = 1 << 16; char bf[bfsz + 5]; int rsz = 0;int ptr = 0; char gc() { if (rsz <= 0) { ptr = 0; rsz = fread(bf, 1, bfsz, stdin); if (rsz <= 0) return EOF; } --rsz; return bf[ptr++]; } void ga(char &c) { c = EOF; while (!isalpha(c)) c = gc(); } int gs(char s[]) { int l = 0; char c = gc(); while (isspace(c)) c = gc(); while (c != EOF && !isspace(c)) { s[l++] = c; c = gc(); } s[l] = '\0'; return l; } template<class T> bool gi(T &v) { v = 0; char c = gc(); while (c != EOF && c != '-' && !isdigit(c)) c = gc(); if (c == EOF) return false; bool neg = c == '-'; if (neg) c = gc(); while (isdigit(c)) { v = v * 10 + c - '0'; c = gc(); } if (neg) v = -v; return true; } const double PI = 2 * acos(0); const string months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; const int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int dr[] = {-1, +0, +1, +0}; const int dc[] = {+0, +1, +0, -1}; const int inf = (int)1e9 + 5; const ll linf = (ll)1e16 + 5; const ld eps = ld(1e-9); const ll mod = 100000007; typedef pair<int, int> II; #define maxn 5005 struct Point{ ld x, y; Point(){}; Point(ld _x, ld _y){ x = _x; y = _y; } }; bool dcmp(ld u, ld v){ return abs(u - v) < eps; } double giao(Point P0, Point P1, double y){ return (P1.x - P0.x) * (y - P0.y) / (P1.y - P0.y) + P0.x; } int n; Point A[maxn]; bool thoaman(double y){ double xl = -double(linf), xr = double(linf), x; For(i, 1, n - 1){ if(!dcmp(A[i].y, A[i + 1].y)) { x = giao(A[i], A[i + 1], y); if(A[i].y > A[i + 1].y) xl = max(xl, x); else xr = min(xr, x); } else if(y + eps < A[i].y){ return false; } } return xr > xl; } int main(){ // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); cin >> n; For(i, 1, n) cin >> A[i].x >> A[i].y; ld u = 0, v = 1000001, mid; Rep(run, 100){ mid = (u + v) / 2; if(thoaman(mid)) v = mid; else u = mid; } cout << fixed << setprecision(2); cout << u; }  #### Code mẫu của ll931110 {$N+}
program spil;
const
input  = '';
output = '';
maxn = 5000;
maxv = 1000000;
maxt = 1000000000;
eps = 1e-6;
type
point = record
x,y: extended;
end;
line = record
a,b,c: extended;
end;
var
p: array[1..maxn] of point;
d: array[1..maxn] of line;
n: longint;
res: extended;

procedure init;
var
f: text;
i: longint;
begin
assign(f, input);
reset(f);

for i := 1 to n do readln(f, p[i].x, p[i].y);

close(f);
end;

procedure expand(i: longint);
begin
with d[i] do
begin
a := p[i].y - p[i + 1].y;
b := p[i + 1].x - p[i].x;
c := -(a * p[i].x + b * p[i].y);
end;
end;

function ok(q: extended): boolean;
var
low,high,tmp: extended;
i: longint;
begin
low := -maxt;
high := maxt;

for i := 1 to n - 1 do if p[i].y = p[i + 1].y then
begin
if q < p[i].y then exit(false);
if q = p[i].y then
begin
if low < p[i].x then low := p[i].x;
if high > p[i].x then high := p[i].x;
end;
end
else
begin

with d[i] do
tmp := -(c + b * q)/a;

if (p[i].y > p[i + 1].y) and (low < tmp) then low := tmp;
if (p[i].y < p[i + 1].y) and (high > tmp) then high := tmp;
end;

ok := (high >= low);
end;

procedure solve;
var
inf,sup,med: extended;
i: longint;
begin
for i := 1 to n - 1 do expand(i);

inf := 0;
sup := maxv;
repeat
med := (inf + sup) / 2;
if ok(med) then
begin
res := med;
sup := med;
end
else inf := med;
until sup - inf < eps;
end;

procedure printresult;
var
f: text;
begin
assign(f, output);
rewrite(f);
writeln(f, res:0:2);
close(f);
end;

begin
init;
solve;
printresult;
end.


#### Code mẫu của khuc_tuan

#include <iostream>
using namespace std;

struct Point {
int x, y;
Point() {}
Point(int x,int y) : x(x), y(y) {}
};

int n;
Point a[5050];

bool checkok(double Y) {
double lower = a[0].x, upper = a[n-1].x;
for(int i=0;i+1<n;++i) {
// a[i] -> a[i+1]
if(a[i].y==a[i+1].y) {
if(a[i].y > Y) return false;
}
else {
double X = (Y - a[i+1].y) * (a[i+1].x - a[i].x) / (a[i+1].y - a[i].y) + a[i+1].x;
if(a[i+1].y>a[i].y) upper = min( upper, X);
else lower = max( lower, X);
}
}
return lower <= upper;
}

int main() {
scanf("%d", &n);
for(int i=0;i<n;++i)
scanf("%d%d", &a[i].x, &a[i].y);
double left = 0, right = 1000000;
for(int kk=0;kk<50;++kk) {
double mid = (left+right) / 2;
if(checkok(mid)) right = mid;
else left = mid;
}
printf("%.2f\n", left);
return 0;
}