문제
제주 올레길 코스로 유명한 산책로가 있다. 산책로의 입구는 산책로에서 가장 서쪽에 위치하고 있다. 이 산책로는 단순 경로이며 수평 구간과 수직 구간으로만 구성되어 있어 모든 코너에서 90도 각도로 왼쪽 또는 오른쪽으로 회전만 할 수 있다. 또한 입구에서 출구 방향으로 걸어갈 때 동쪽에서 서쪽으로 이동을 전혀 하지 않아도, 즉, 보행자의 현재 위치를 나타내는 좌표의 x축 값이 작아지는 경우가 없이도 출구까지 도달할 수 있다. 그래서 이 산책로를 모노톤길이라고 부른다. 그림 1은 모노톤길의 예를 보여준다.
그림 1. 모노톤길의 예
이 산책로에는 n개의 카페가 곳곳에 들어서 있다. 특히 입구와 출구, 그리고 모든 코너에는 카페가 들어서 있다. 올레길 코스 관리자인 김씨는 이 산책로에 들어서 있는 모든 카페들의 위치 좌표를 가지고 있다. 입구 좌표는 항상 원점 (0,0) 이다. 그는 이들 카페에 1부터 n까지의 일렬 번호를 붙이려고 한다. 입구의 카페는 1번, 그 다음부터는 길을 따라가면서 만나는 순서대로 번호를 배정한다. 입구에서 출구로 갈 때, 카페 A를 카페 B보다 먼저 만나게 된다면, A에는 B보다 더 작은 번호를 배정한다. 따라서 그림 1의 산책로에서 좌표 (3,1)에 위치한 카페의 번호는 5이고, 좌표 (9,0)에 위치한 카페는 14번이고, 출구의 카페는 17번이다. 그는 산책로를 직접 걷지 않고 카페의 좌표들만으로 이 작업을 수행하고 싶어 한다. 그를 도와서 카페에 번호를 붙이는 작업을 수행하는 프로그램을 작성하시오.
입력
입력 데이터는 표준입력을 사용한다. 입력은 T개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 테스트 데이터의 개수 T가 정수로 주어진다. 각 테스트 데이터의 첫 번째 줄에는 카페의 수를 나타내는 정수 n (2 ≤ n ≤ 100,000)이 주어진다. 그 다음 n개의 줄에는 각 줄마다 각 카페의 좌표 (x,y)를 나타내는 두 개의 정수 x와 y가 주어진다. (0 ≤ x ≤ 100,000, -100,000 ≤ y ≤ 100,000). 입구 좌표는 항상 (0,0)이다. 어떤 두 카페도 동일한 좌표를 가지는 경우는 없다. 마지막 줄에는 정수 m (1 ≤ m ≤ 10)과 m개의 정수가 주어진다. m개의 각 정수는 1 이상 n 이하로서 카페의 번호를 나타낸다.
출력
출력은 표준출력을 사용한다. 각 테스트 데이터에 대해, 카페 번호로서 주어진 m개의 정수에 대한 답을 순서대로 한 줄에 하나씩 출력한다. 정수 k에 대한 답은 번호가 k인 카페의 좌표 (x,y)를 나타내는 두 개의 정수 x와 y이다.
예제
// 입력
2
17
3 3
5 3
11 2
9 2
2 1
3 1
5 1
0 0
1 0
2 0
9 0
11 -1
9 -3
6 -1
7 -1
7 -3
5 -1
3 5 14 17
4
0 0
0 1
1 1
1 0
5 1 4 1 3 1
// 출력
3 1
9 0
11 -1
0 0
1 0
0 0
1 1
0 0
코드
// cpp 17
#include <iostream>
#include <algorithm>
using namespace std;
pair<int, int> pos[100001];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int test;
for (cin >> test; test--;)
{
int N;
cin >> N;
for (int i = 1; i <= N; i++)
cin >> pos[i].first >> pos[i].second;
// 다시 되돌아갈 수 없으므로 x 값을 기준으로 정렬한다.
// pair는 first가 같으면 second를 기준으로 정렬한다.
sort(pos + 1, pos + 1 + N);
for (int i = 1, e; i < N; i = e)
{
// x값이 같은 구간을 구한다.
e = upper_bound(pos + 1, pos + 1 + N, make_pair(pos[i].first, int(1e9))) - pos;
// 이전 구간의 y값과 다르면 뒤집어주면 된다.
// 왜냐하면, 길은 무조건 있기 때문이다.
if (pos[i].second != pos[i - 1].second)
reverse(pos + i, pos + e);
}
int M;
cin >> M;
while (M--)
{
int n;
cin >> n;
printf("%d %d\n", pos[n].first, pos[n].second);
}
}
}
'Outdated > Algorithm Solution' 카테고리의 다른 글
[BOJ] 2665번 미로만들기 (0) | 2019.05.27 |
---|---|
[BOJ] 9020번 골드바흐의 추측 (0) | 2019.05.26 |
[BOJ] 3036번 링 (0) | 2019.05.24 |
[BOJ] 1003번 피보나치 함수 (0) | 2019.05.23 |
[BOJ] 10250번 ACM 호텔 (0) | 2019.05.22 |