fragment-header
fragment-markdown
홈
로그인
로그아웃
내 블로그
설정
로그인
백준 10254 (C++) 고속도로
최초 업로드: 2025-08-15 15:09:28
최근 수정 시간: 2025-08-15 21:27:45
게시자: rlatjwls3333
카테고리: 백준
조회수: 7
# [Platinum II] 고속도로 [문제 링크](https://www.acmicpc.net/problem/10254) ## 문제 설명 <p>n개의 도시를 가진 나라가 있다. 이 나라에서는 도시들 중 가장 먼 두 도시 사이에 직행 고속도로를 놓으려 한다.</p> <p>고속도로는 시작점과 끝점이 아닌 다른 나라를 통과해도 된다. 즉, n개의 도시 중 유클리드 거리가 가장 먼 두 도시를 찾으려 한다. 모든 도시는 한 평면 위에 있다.</p> <p><img src="https://www.acmicpc.net/upload/images2/highway(1).png"></p> <p>위의 예제에서는 (12,0)의 도시와 (-6,3)의 도시가 가장 먼 유클리드 거리를 갖는다.</p> <p>도시 n개의 좌표가 주어지면 모든 두 도시 쌍의 거리 중 가장 먼 두 도시를 찾아라.</p> ## 입력 <p>첫째 줄에 테스트 케이스의 수 T가 주어진다. </p> <p><span style="line-height:1.6em">각 테스트 케이스의 첫 줄엔 도시의 개수 n이 주어진다. (</span><span style="line-height:1.6em">2 ≤ n ≤ 200,000</span><span style="line-height:1.6em">) </span><span style="line-height:1.6em">그 후 n줄에 걸쳐 각 도시의 x좌표와 y좌표가 주어진다. (-10,000,000 ≤ x, y ≤ 10,000,000) </span><span style="line-height:1.6em">x, y는 항상 정수이며, 어떤 두 도시가 같은 점 위에 있는 경우는 없다.</span></p> ## 출력 <p>테스트 케이스마다 가장 먼 두 점의 좌표를 출력한다.</p> <p>만일 그 두 점의 좌표가 각각 (x1, y1), (x2, y2)이라면 x1 y1 x2 y2를 출력하면 된다.</p> <p>가장 먼 거리를 갖는 두 점의 쌍이 여러 개라면 그 중 아무 것이나 출력해도 상관없다.</p> ## 풀이 #### 그라함 스캔과 회전하는 캘리퍼스 알고리즘을 사용하여 풀었다. ``` c++ #include<bits/stdc++.h> using namespace std; typedef long long ll; struct pos { ll x, y, p=0, q=0; bool operator<(const pos o) const { if(p*o.q!=q*o.p) return p*o.q > q*o.p; if(y!=o.y) return y < o.y; return x < o.x; } }; ll ccw(pos a, pos b, pos c) { pos vec1 = {b.x-a.x, b.y-a.y}; pos vec2 = {c.x-b.x, c.y-b.y}; return vec1.x*vec2.y - vec1.y*vec2.x; } ll ccw(pos a, pos b, pos c, pos d) { pos vec1 = {b.x-a.x, b.y-a.y}; pos vec2 = {d.x-c.x, d.y-c.y}; return vec1.x*vec2.y - vec1.y*vec2.x; } vector<pos> graham_Scan() { int n; cin >> n; vector<pos> v(n); for(int i=0;i<n;i++) cin >> v[i].x >> v[i].y; sort(v.begin(), v.end()); for(int i=1;i<n;i++) { v[i].p = v[i].x - v[0].x; v[i].q = v[i].y - v[0].y; } sort(v.begin(), v.end()); vector<pos> stk; for(int i=0;i<n;i++) { while(stk.size()>=2 && ccw(stk[stk.size()-2], stk[stk.size()-1], v[i])<=0) stk.pop_back(); stk.push_back(v[i]); } return stk; } ll dist(pos a, pos b) { return (b.x-a.x)*(b.x-a.x) + (b.y-a.y)*(b.y-a.y); } void rotating_Calipers(vector<pos> stk) { int n = stk.size(); pos a, b; ll maxDist=0; int i=0, j=1; while(i<n && j<n) { ll curDist = dist(stk[i], stk[j]); if(curDist>maxDist) { maxDist = curDist; a = stk[i]; b = stk[j]; } if(ccw(stk[i], stk[(i+1)%n], stk[j], stk[(j+1)%n])>0) j++; else i++; } cout << a.x << ' ' << a.y << ' ' << b.x << ' ' << b.y << '\n'; } int main() { ios::sync_with_stdio(0); cin.tie(0); int t; cin >> t; while(t--) { rotating_Calipers(graham_Scan()); } } ```