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

Code mẫu của ladpro98

#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;
}

Code mẫu của RR

{$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);

  readln(f, n);
  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;
}

Comments

Please read the guidelines before commenting.


There are no comments at the moment.