Editorial for Farthest Headquarters


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 happyboy99x

#include<complex>
#include<vector>
#include<algorithm>
#include<climits>
#include<cmath>
#include<iostream>
using namespace std;

#define TR(v,i) for(__typeof((v).begin())i=(v).begin();i!=(v).end();++i)
#define TRR(v,i) for(__typeof((v).rbegin())i=(v).rbegin();i!=(v).rend();++i)
typedef complex<long long> Point;

long long cross(const Point &a, const Point &b) {
    return (conj(a) * b).imag();
}

bool cmp(const Point &a, const Point &b) {
    return a.real() == b.real() ? a.imag() < b.imag() : a.real() < b.real();
}

vector<Point> convexhull(vector<Point> &p) {
    sort(p.begin(), p.end(), cmp);
    vector<Point> hull; int k = 0;
    TR(p, it) {
        while(k > 1 && cross(hull[k-1]-hull[k-2], *it-hull[k-2]) <= 0)
            hull.pop_back(), --k;
        hull.push_back(*it); ++k;
    }
    int t = k; TRR(p, it) {
        while(k > t && cross(hull[k-1]-hull[k-2], *it-hull[k-2]) <= 0)
            hull.pop_back(), --k;
        hull.push_back(*it); ++k;
    }
    return hull;
}

long long maxdist(const vector<Point> &p, const vector<Point> &q) {
    long long res = 0;
    TR(p, i) TR(q, j) res = max(res, norm(*j - *i));
    return res;
}

vector<Point> p[2];

void enter() {
    p[0].clear(); p[1].clear();
    int n; cin >> n;
    for(int i = 0; i < n; ++i) {
        int a, b, c; cin >> a >> b >> c;
        p[c].push_back(Point(a, b));
    }
}

int main() {
    ios::sync_with_stdio(false);
    int tc; cin >> tc;
    while(tc--) {
        enter();
        cout << (int) sqrt(maxdist(convexhull(p[0]), convexhull(p[1]))) << endl;
    }
    return 0;
}

Code mẫu của ladpro98

#include <iostream>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <climits>
#include <numeric>
#include <vector>
#include <queue>
#include <map>
#include <utility>
#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 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>
#define VII vector<II>
using namespace std;

void operator -= (II &a, II b) {a.X -= b.X; a.Y -= b.Y;}
bool ccw(II a, II b, II c) {c -= b; b -= a; return (LL)b.X * c.Y > (LL)b.Y * c.X;}

void refine(VII &a) {
    VII hull;
    sort(ALL(a));
    #define S hull.size()
    FOR(i, 0, SZ(a)) {
        while (S > 1 && ccw(hull[S - 2], hull[S - 1], a[i])) hull.pop_back();
        hull.PB(a[i]);
    }
    int t = S;
    REPD(i, SZ(a) - 2, 0) {
        while (S > t && ccw(hull[S - 2], hull[S - 1], a[i])) hull.pop_back();
        hull.PB(a[i]);
    }
    a = hull;
}

LL dist(II a, II b)
    {return (LL)(a.X - b.X) * (a.X - b.X) + (LL)(a.Y - b.Y) * (a.Y - b.Y);}

int main() {
    ios :: sync_with_stdio(0); cin.tie(0);
    int ntest, n, x, y, c;
    cin >> ntest;
    while (ntest--) {
        cin >> n;
        VII poly[2];
        FOR(i, 0, n) {
            cin >> x >> y >> c;
            poly[c].PB(MP(x, y));
        }
        FOR(i, 0, 2) refine(poly[i]);
        LL ans = 0;
        FOR(i, 0, SZ(poly[0]))
        FOR(j, 0, SZ(poly[1]))
            ans = max(ans, dist(poly[0][i], poly[1][j]));
        int d = int(sqrt(ans));
        if (d * d > ans) cout << d - 1 << '\n';
        else cout << d << '\n';
    }
    return 0;
}

Code mẫu của RR

#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <cstdio>

#define FOR(i,a,b) for(int i=(a),_b=(b); i <= _b; ++i)
#define FR(i,a) for(int i=0,_a=(a); i < _a; ++i)
using namespace std;

const double eps = 1e-10;
int cmp(double q,double w) {
    return (q < w + eps) ? (q > w - eps) ? 0 : -1 : 1;
}
struct point {
    double x,y;
    point (double x,double y): x(x),y(y) {}
    point () {x=y=0.0; }
    point operator +(point q) { return point(x+q.x,y+q.y); }
    point operator -(point q) { return point(x-q.x,y-q.y); }
    point operator *(double t) { return point(x*t,y*t); }
    point operator /(double t) { return point(x/t,y/t); }
    double operator *(point q){ return q.x * x + q.y * y; }
    double operator %(point q){ return x*q.y - y*q.x; }
    int cmp(point q) const { if(int t = ::cmp(x,q.x)) return t; return ::cmp(y,q.y); }
    #define Comp(x) bool operator x (point q) const { return cmp(q) x 0; }
    Comp(>) Comp(<) Comp(==) Comp(>=) Comp(<=) Comp(!=)
    #undef Comp

    double sqlen() { return x*x + y*y; }
};
typedef vector<point> polygon;
inline int ccw(point a, point b, point c) {
    return cmp((b-a)%(c-a),0); 
}
double area(polygon &p) {
    double s = 0.0;
    FOR(i,1,(int)p.size()-1) s+= (p[i]-p[0])%(p[(i+1)%p.size()]-p[0]);
    return fabs(s) / 2.0;
}
struct comp_hull {
    point pivot;
    bool operator() (point q,point w) {
        point Q = q - pivot, W = w - pivot;
        double R = Q % W;
        if (cmp(R,0)) return R < 0;
        return cmp(Q*Q,W*W) < 0;
    }
};
polygon convex_hull(polygon p) { // minimum vertices
    int j = 0, k, n = p.size();
    polygon r(n);
    if (!n) return r;
    comp_hull comp;
    comp.pivot = *min_element(p.begin(),p.end());
    sort(p.begin(),p.end(),comp);
    FR(i,n) {
        while (j > 1 && ccw(r[j-1],r[j-2],p[i]) <= 0) j--;
        r[j++] = p[i];
    }
    r.resize(j);
    return r;
}

const int MN = 30111;
int x[MN], y[MN], t[MN];

int main() {
    int ntest; scanf("%d", &ntest);
    while (ntest--) {
        polygon a, b;
        int n; scanf("%d", &n);
        FOR(i,1,n) {
            scanf("%d%d%d", &x[i], &y[i], &t[i]);
            if (t[i] == 0) a.push_back(point(x[i], y[i]));
            else b.push_back(point(x[i], y[i]));
        }

        a = convex_hull(a); b = convex_hull(b);

        double res = -1;
        FR(i,a.size()) FR(j,b.size()) {
            res = max(res, (a[i] - b[j]).sqlen());
        }

        printf("%d\n", (int) (sqrt(res) + 1e-6));
    }
}

Code mẫu của hieult

#include<cstdio>
#include<cmath>
#include<math.h>
#include<cstring>
#include<cstdlib>
#include<cassert>
#include<ctime>
#include<algorithm>
#include<iterator>
#include<iostream>
#include<cctype>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<list>
#define ep 0.00001
#define maxn 30111
#define oo 1111111111
#define modunlo 111539786
#define TR(c, it) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++)
#define g 9.81
double const PI=4*atan(1.0);

using namespace std;

struct Point {
       int x, y;
       Point() {};
       Point(int _x, int _y) {
              x = _x;
              y = _y;
       }
};

Point O;

int ccw(Point A, Point B, Point C) {
    long long dx1 = B.x - A.x, dy1 = B.y - A.y;
    long long dx2 = C.x - A.x, dy2 = C.y - A.y;
    long long ret = dx1 * dy2 - dx2 * dy1;
    if (ret == 0) return 0;
    return ret < 0 ? -1 : +1;
}

long long sqr(int x) {
     return (long long) x * x;
}

long long sqrdist(Point P1, Point P2) {
     return sqr(P1.x - P2.x) + sqr(P1.y - P2.y);
}

bool nearer(Point P1, Point P2) {
     return sqrdist(O, P1) < sqrdist(O, P2);
}

bool cmp(Point P1, Point P2) {
     int c = ccw(O, P1, P2);
     if (c != 0) return c > 0;
     return nearer(P1, P2);
}

void graham(Point a[], int &n) {
     int imin = 0;
     for (int i = 1; i < n; ++i) {
         if (a[imin].y > a[i].y) imin = i;
         else if (a[imin].y == a[i].y && a[imin].x > a[i].x) imin = i;
     }

     O = a[imin];     
     swap(a[0], a[imin]);
     sort(a + 1, a + n, cmp);

     int inow = 1;
     for (int i = 2; i < n; ++i) {
         while (inow > 0 && ccw(a[i], a[inow], a[inow - 1]) >= 0) --inow;
         ++inow;
         swap(a[inow], a[i]);         
     }

     n = inow + 1;
}

bool cmpYX(Point P1, Point P2) {
     if (P1.y != P2.y) return P1.y < P2.y;
     return P1.x < P2.x;
}

Point G[maxn],M[maxn];
int test,n,n1,n2,x,y,c;

int main() {
//    freopen("_.in", "r", stdin);
   // freopen("output.out", "w", stdout);
    scanf("%d",&test);
    for(int itest = 0;itest<test;itest++){
         scanf("%d",&n);
         n1 = 0,n2 = 0;
         for(int i = 0;i<n;i++){
               scanf("%d %d %d",&x,&y,&c);
               if(c){
                    G[n1++] = Point(x,y);
               }
               else{
                    M[n2++] = Point(x,y);
               }
         }
         graham(G,n1);
         graham(M,n2);
         long long MAX = 0;
         for(int i = 0;i<n1;i++) for(int j = 0;j<n2;j++) MAX = max(MAX,sqrdist(G[i],M[j]));
         printf("%d\n",int(sqrt(MAX))); 
    }

    return 0;
}

Code mẫu của skyvn97

#include<cstdio>
#include<cmath>
#include<algorithm>
#define MAX   30303
#define INF   1e9
using namespace std;
typedef long long ll;
struct point {
    ll x,y;
    point(){
        x=0;y=0;
    }
    point(const ll &_x,const ll &_y) {
        x=_x;y=_y;
    }
    point operator + (const point &a) const {
        return (point(x+a.x,y+a.y));
    }
    point operator - (const point &a) const {
        return (point(x-a.x,y-a.y));
    }
    ll operator ^ (const point &a) const {
        return (x*a.y-a.x*y);
    }
    bool operator < (const point &a) const {
        if (y<a.y) return (true);
        if (y>a.y) return (false);
        return (x<a.x);
    }
};
struct stack {
    int size;
    point bd[MAX];
    stack(){}
    void clear(void) {
        size=0;
    }
    void push(const point &v) {
        size++;
        bd[size]=v;
    }
    void pop(void) {
        size--;
    }
    bool empty(void) {
        return (size==0);
    }
    point operator [] (const int &i) {
        return (bd[i]);
    }
};
int ccw(const point &a,const point &b,const point &c) {
    ll cp=(b-a)^(c-a);
    if (cp==0) return (0);
    if (cp<0) return (-1);
    if (cp>0) return (1);
}
bool cmp(const point &a,const point &b) {
    int t=ccw(point(),a,b);
    if (t>0) return (true);
    if (t<0) return (false);
    return (a.y<b.y);
}
int m,n,p;
point a[MAX];
point b[MAX];
point da,db;
stack ca,cb;
void swap(point &a,point &b) {
    point sw;
    sw=a;a=b;b=sw;
}
void init(void) {
    m=0;n=0;
    int i,t;
    ll x,y;
    scanf("%d",&p);
    for (i=1;i<=p;i=i+1) {
        scanf("%lld",&x);
        scanf("%lld",&y);
        scanf("%d",&t);
        if (t==0) {
            m++;
            a[m]=point(x,y);
        }
        else {
            n++;
            b[n]=point(x,y);
        }
    }
}
void convert_hull(const int &m,point a[],point &da,stack &ca) {
    da=point(INF,INF);
    int i,im;
    for (i=1;i<=m;i=i+1)
        if (a[i]<da) {
            da=a[i];
            im=i;
        }
    swap(a[1],a[im]);
    for (i=1;i<=m;i=i+1) a[i]=a[i]-da;
    sort(&a[2],&a[m+1],cmp);
    ca.clear();
    for (i=1;i<=m;i=i+1) {
        if (ca.size<2) {
            ca.push(a[i]);
        }
        else {
            while (ccw(ca[ca.size-1],ca[ca.size],a[i])<=0 && ca.size>1) ca.pop();
            ca.push(a[i]);
        }
    }
}
ll dis(const point &a,const point &b) {
    return (floor(hypot(a.x-b.x,a.y-b.y)));
}
ll max(const ll &x,const ll &y) {
    if (x>y) return (x); else return (y);
}
void process(void) {
    convert_hull(m,a,da,ca);
    convert_hull(n,b,db,cb);
    ll res=-1;
    int i,j;
    for (i=1;i<=ca.size;i=i+1)
        for (j=1;j<=cb.size;j=j+1)
            res=max(res,dis(ca[i]+da,cb[j]+db));
    printf("%lld\n",res);
}
int main(void) {
    int t,c;
    scanf("%d",&t);
    for (c=1;c<=t;c=c+1) {
        init();
        process();
    }
    return 0;
}

Comments

Please read the guidelines before commenting.


There are no comments at the moment.