← Back to List

10254번: 고속도로 ↗

Solutions

C++14
2.7 KB | 2799 chars
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <cmath>

#define MX 220000

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
typedef unsigned int uint;
typedef vector <ull> ullv1;
typedef vector <vector <ull>> ullv2;

struct point{
    ll x,y;
    ll p=0,q=0;
};

bool comp1(point a, point b) {
    if(a.y != b.y) return a.y < b.y;
    return a.x < b.x;
}

bool comp2 (point a, point b) {
    if(a.q * b.p != a.p*b.q)
        return a.q * b.p < a.p*b.q;
    return comp1(a,b);
}

ull dist(point a, point b) {
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

ll ccw(point p1, point p2, point p3) {
    return (p1.x * p2.y + p2.x * p3.y + p3.x * p1.y - p2.x * p1.y - p3.x * p2.y - p1.x * p3.y);
}

ll N,tc;
vector <point> ar;
point Z;
point ans_a, ans_b;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> tc;
    while(tc--) {

        stack <int> stk;
        while (!stk.empty()) stk.pop();
        ar.clear();

        cin >> N;
        for(int x=0; x<N; x++) {
            cin >> Z.x >> Z.y;
            ar.push_back(Z);
        }

        // Graham scan
        sort(ar.begin(),ar.end(),comp1);
        for(int x=1; x<N; x++) {
            ar[x].p = ar[x].x - ar[0].x;
            ar[x].q = ar[x].y - ar[0].y;
        }
        sort(ar.begin()+1,ar.end(),comp2);
        stk.push(0);
        stk.push(1);
        int next = 2;
        while(next < ar.size()) {
            while(stk.size() >= 2) {
                int s = stk.top();
                stk.pop();
                int f = stk.top();
                if(ccw(ar[f],ar[s],ar[next]) > 0) {
                    stk.push(s);
                    break;
                }
            }
            stk.push(next++);
        }

        vector <int> nums;
        nums.clear();
        while(!stk.empty()) {
            nums.push_back(stk.top());
            stk.pop();
        }
        reverse(nums.begin(), nums.end());

        int j = 1;
        ull ans = 0, sz = nums.size();
        for(int i = 0; i < sz; i++) {
            int iNext = (i+1) % sz;
            while(1) {
                int jNext = (j+1) % sz;
                ll k = ccw({0, 0}, {ar[nums[iNext]].x-ar[nums[i]].x, ar[nums[iNext]].y-ar[nums[i]].y}, {ar[nums[jNext]].x-ar[nums[j]].x, ar[nums[jNext]].y-ar[nums[j]].y});
                if(k > 0) {
                    j = jNext;
                }else break;
            }
            ull d = dist(ar[nums[i]],ar[nums[j]]);
            if(ans < d) {
                ans = d;
                ans_a = ar[nums[i]];
                ans_b = ar[nums[j]];
            }
        }

        cout << ans_a.x << " " << ans_a.y << " " << ans_b.x << " " << ans_b.y << "\n";
    }
}