[Java] 백준 11650번 [좌표 정렬하기] 자바

: ) YOUNG·2022년 2월 23일
2

알고리즘

목록 보기
57/417
post-thumbnail

백준 11650번
https://www.acmicpc.net/problem/11650


문제

2차원 평면 위의 점 N개가 주어진다. 좌표를 x좌표가 증가하는 순으로, x좌표가 같으면 y좌표가 증가하는 순서로 정렬한 다음 출력하는 프로그램을 작성하시오.


입력

첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.


생각하기

이름만 들어도 어떤 문제인지 알 수 있다.
좌표정렬하기 그냥 정렬문제이다.

근데 어렵다.. x좌표와 y좌표를 활용하라는 내용을 보니까 2차원 배열을 써야 될 것 같은데 한참 고민하다 다른 분들의 코드를 참조하기로 했다.

1. https://st-lab.tistory.com/110
2. https://ehdals9412.tistory.com/25

처음에 2차원 배열을 활용하는 것 까지는 맞았다.
문제는 내가 2차원 배열은 정렬을 할 줄 모른다는 것..

첫번째는 Arrays.sort()에 람다식을 확장 시켜주는 것이다..

먼저 입력받는 값 들로 2차원 배열을 생성하고,

Arrays.sort(arr, (arr_1, arr_2) -> {} 의 형식으로 기존의 Arrays.sort()를 조금 수정하는 것(?) 이라고 해도 될 것 같다.

2차원 배열의 x값 끼리 먼저 비교 후 x값이 같을 경우 y값을 기준으로 하기 때문에
이런 비교 조건을 우리가 만들어 주는 것이다.

arr 배열에서 첫번째는 arr_1 두번째는 arr_2로 해서
arr_1[0]arr_2[0] 2개가 x값 이므로 비교해서 같을 경우
arr_1[1]arr_2[1] 가 y값 이므로 두 값을 비교한다.

여기서 arr_1[1]arr_2[1] 을 빼서 arr_1[1]이 더 클 경우 위치를 바꾸게 된다.

쉽게 말해서 return 되는 값이
음수 일 경우 : 위치를 바꾸지 않음
양수일 경우 : 위치를 바꿈

이라는 조건으로 가게 된다.
이 방식으로 2차원 배열을 정렬하면 정상적인 출력값을 얻을 수 있다.

두번째 방식은 비슷하지만 람다식을 사용하지 않고 조금 더 기초적으로 접근 한 방식이다.

당연히 첫번째 방법이 더 빠르고 간결하지만 그래도 동작방식의 기초를 알고가는 것은 굉장히 중요하기 때문에 따로 찾아보았다.

여기서도 Arrays.sort() 까지는 똑같지만 Comparator 인터페이스를 가져와서 수정한다.

Comparatorcompare 메소드를 오버라이드 해서 재정의 해주는 것이다.

원래 Arrays.sort()에서 mergesort에서도 compare 메소드를 사용하기 때문에 이 방법이 가능하다.

이 부분에서 몰랐는데 새로 알게 된 점은 객체형의 Integer를 비교할 때는 == 이 아닌 equals를 사용해야 된다는 것을 알게 됬다.

정렬을 공부하며 비교과정까지 공부하게 되고 알게 되었지만 Comparator 진짜 중요하고 유용한 것 같다.


TMI

람다식은 처음 접해 봤는데, 간결하고 도움도 많이 될 것 같다는 생각이 든다.

앞으로 좀 파볼까?



코드

Arrays.sort() 람다식 해결

import java.util.*;
import java.io.*;

public class Main {
	static int arr[][];

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();

		int N = Integer.parseInt(br.readLine());
		arr = new int [N][2];

		for(int i=0; i<N; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			arr[i][0] = Integer.parseInt(st.nextToken());
			arr[i][1] = Integer.parseInt(st.nextToken());
		}

		Arrays.sort(arr, (arr_1, arr_2) -> {

			if(arr_1[0] == arr_2[0])  {
				return arr_1[1] - arr_2[1];
			}
			else {
				return arr_1[0] - arr_2[0];	
			}
		});

		for(int i=0; i<N; i++) {
			sb.append(arr[i][0] + " " + arr[i][1]).append('\n');
		}

		System.out.println(sb);
	}
}


Arrays.sort()에서 Comparator 인터페이스 사용

import java.io.*;
import java.util.*;
import java.util.Comparator;

public class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = null;
		StringBuilder sb = new StringBuilder();
		
		int N = Integer.parseInt(br.readLine());
		Integer arr[][] = new Integer[N][2];

		for(int i=0; i<N; i++) {
			st = new StringTokenizer(br.readLine());
			arr[i][0] = Integer.parseInt(st.nextToken());
			arr[i][1] = Integer.parseInt(st.nextToken());
		}

		Arrays.sort(arr, new Comparator<Integer[]>() {
			@Override
			public int compare(Integer[] o1, Integer[] o2) {
				if(o1[0].equals(o2[0])) {
					return o1[1] - o2[1];
				}
				else {
					return o1[0] - o2[0];
				}
			}
		});	

		for(int i=0; i<N; i++) {
			sb.append(arr[i][0] + " " + arr[i][1]).append('\n');
		}

		System.out.println(sb);
	}
}

0개의 댓글