점 짝짓기
2차원 평면에 개의 점이 주어진다. 은 짝수이다. 점들은 번부터 번까지 번호가 매겨져 있다. 번 점의 좌표는 이다. 점들을 두 개씩 짝을 지어 개의 쌍을 만들려고 한다. 두 점 과 가 짝이 되었을 때 이 쌍에 대한 점수는 이다.
점수 총합이 가능한 최대가 되도록 점을 짝짓는 프로그램을 작성하라.
입력 형식
첫 줄에 점의 수를 나타내는 정수 이 주어진다. ( 은 짝수)
이어지는 개의 줄의 번째 줄에는 번 점의 좌표를 나타내는 두 정수 , 가 공백으로 구분되어 주어진다. ()
출력 형식
첫 줄에 점수 총합의 최댓값을 출력한다.
그다음 개의 줄에 걸쳐 최대 점수 총합을 만드는 짝짓기 방법을 출력한다. 각 줄은 짝을 짓는 두 점의 번호를 공백으로 구분하여 출력한다.
만약 가능한 답이 여러 가지라면, 그중 아무거나 하나 출력한다.
예제
입력
4 1 2 2 1 2 2 1 1
출력
4 4 3 1 2
예제 설명
번 점과 번 점으로 쌍을 만들어 점을 얻고, 번 점과 번 점으로 쌍을 만들어 점을 얻는다. 점수의 총합은 점이다.
채점 방식
입력 케이스들은 다음과 같은 종류로 구별되며, 한 종류의 케이스를 다 맞혀야 그 종류에 배정된 점수를 받을 수 있다.
종류 1: 19점
종류 2: 18점
모든 점의 좌표가 같음.
종류 3: 63점
추가적인 제한 조건이 없음.
해설
아래 설명은 편의를 위해 각각의 , 좌표가 다르다고 가정한다. 실제로 중복된 좌표가 있더라도 이들을 서로 다른 값으로 취급하여도 풀이는 여전히 유효하다.
우선, 좌표만 있는 1차원의 경우를 생각하자. 편의상 라고 할 때, 두 점 와 를 짝지으면 점수는 이다. 즉, 큰 좌표에 을, 작은 좌표에 을 곱한 값이 점수가 된다. 이렇게 개의 짝을 만든다면 각각의 좌표에 곱할 수 있는 과 이 각각 개 생긴다.
실제로 점을 짝짓는 방법을 생각하기 전에 이상적으로 점수를 최대화하는 방법만 생각하자. 좌표 에 , 에 이 곱해져 있는데 이면, 곱해진 값을 교환하면 반드시 점수에 이득이 된다.
이 과정을 최대한 반복하자. 그러면 결국 좌표를 정렬했을 때 큰 좌표 개에 을, 작은 좌표 개에 을 곱한 상황에 수렴하고 더 이상 교환이 불가능하다. 이 상황이 최대 점수가 되며, 실제로 점을 짝짓는 방법도 쉽게 알 수 있다. 큰 좌표를 가지는 점들과 작은 좌표를 가지는 점들을 일대일로 짝짓는 것이다.
이제 좌표와 좌표가 있는 2차원의 경우를 생각하자. 비슷한 논리를 사용하면 이상적으로 점수를 최대화하는 방법은 , 좌표 각각에 대해 큰 좌표 개에 을 곱하고, 작은 좌표 개에 을 곱하는 것이다. 이것이 가능하게 점들을 짝지을 수 있을까?
좌표와 좌표 각각에 대해 큰 좌표 개와 작은 좌표 개를 반으로 나눌 수 있도록 평면을 4분할 해보자. 이때 1사분면에 개의 점이 들어있다면 2사분면과, 4사분면에는 개, 3사분면에는 개의 점이 들어있게 된다.
1사분면과 3사분면에 들어있는 점들을 일대일로 짝짓고, 2사분면과 4사분면에 들어있는 점들을 일대일로 짝지으면 이것이 이상적으로 점수를 최대화하는 방법을 구현한다는 것을 알 수 있다.