[백준] #11650번 좌표 정렬하기 (Java)

Happy Jiwon·2024년 12월 4일
2

코테

목록 보기
4/8

백준 11650 - 좌표 정렬하기 바로가기

📝 문제 설명

2차원 평면 위의 점 N개가 주어진다.
좌표를 x좌표가 증가하는 순으로,
x좌표가 같으면 y좌표가 증가하는 순서로 정렬한 다음 
출력하는 프로그램을 작성하시오.
  • 생각없이 읽었을 때 이게 뭔 소린가 싶은데 사실은 간단하다
    x를 기준으로 오름차순 하여 출력하는건데, 만약 x값이 같으면 y를 기준으로 오름차순 정렬 후 출력하라는 뜻임

입력
첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다.
둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다.

  • (-100,000 ≤ xi, yi ≤ 100,000)

좌표는 항상 정수이고, 위치가 같은 두 점은 없다.

출력
첫째 줄부터 N개의 줄에 점을 정렬한 결과를 출력한다.

입출력 예시


문제 들여다 보기..

  • 위 정렬 부분은 이전 회의실 배정 문제에서 사용한 정렬과 같음

  • 즉, Arrays.sort()Comparator를 사용해 x를 기준으로 정렬하고 x 값이 같다면 y를 기준으로 정렬하도록 코드를 작성했다.


📌 풀이

...
...
public class Main {
    public static void main(String[] args) throws IOException {
        int n = 5;
        int[][] plane = {{3, 4}, {1, 1}, {1, -1}, {2, 2}, {3, 3}};
        
        // x기준으로 오름차순 정렬, 만약 같다면 y기준으로 오름차순 정렬
        Arrays.sort(plane, (o1, o2) -> {
            if (o1[0] == o2[0]) { // x가 같을경우 y기준 오름차순 정렬
                return o1[1] - o2[1];
            }
            return o1[0] - o2[0];
        });
        
------------------------------------------------------------------
		// 정답 양식에 맞게 출력문 작성
        for (int x = 0; x < n; x++) {
            for (int y = 0; y < 2; y++) {
                System.out.print(plane[x][y] + " ");
            }
             System.out.println();
        }
    }
}

📚 코드 설명

1️⃣ 입력 처리 및 배열 생성
사용자로부터 N 값을 입력받아 처리
N 은 1 ≤ N ≤ 100,000 로 제한
(입출력 예시로 5로 초기화 설정함)

2️⃣ 정렬
Arrays.sort()와 Comparator를 사용해 x(i)값을 기준 오름차순으로 정렬한다.
x(i)가 같다면 o1[1] - o2[1] : y(i)값을 기준으로 오름차순 정렬

3️⃣ 출력

for(int i = 0; i < n; i++) {
	System.out.println(Arrays.toString(plane[i]));
}

만약 위와같이 출력한다면 배열이기 때문에 아래와 같이 나온다. 그럼 틀린거임

생각하고 출력하도록.
(나한테 하는말임)


출력문 하수 ver

처음 작성한 출력문은 바로 통과했지만 너무 길어서 짧게 줄이고자 포맷 문자열을 사용해서 제출했다.

// 시간초과 코드
 for (int[] plane : planes) {
	System.out.printf("%d %d%n", plane[0], plane[1]);
}

결과는 당연히 시간초과^.^.. 흑흑

이유는 간단함. printf 는 System.out.print() 보다 출력문이 많을때 성능저하를 발생시키기 때문이다.

그렇지만 짧게 줄이는건 포기할수없따....

출력문 수정

해결 방법으로 문자열을 한 번에 출력하는 방식 StringBuilder를 활용했다.
문자열을 연결해주는 append 사용

// 수정한 출력문 (StringBuilder 사용)
StringBuilder sb = new StringBuilder();
for (int[] plane : planes) {
    sb.append(plane[0]).append(" ").append(plane[1]).append("\n");
}
System.out.print(sb);

사실 내 기준으로는 중첩 for문으로 출력한게 더 직관적이지만,
출력 횟수가 많으면 성능 저하, 비효율적이기 때문에
StringBuilder가 (간지나 보이긴 함) 효율적으로 사용하기 좋다.


📌 전체 코드

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

        // i번점의 위치 x(i)와 y(i) 입력
        int[][] plane = new int[n][2];
        StringTokenizer st;
        for (int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine()); // ex) 3 4 저장
            // x(i) 저장
            plane[i][0] = Integer.parseInt(st.nextToken()); // ex) 3 저장
            // y(i) 저장
            plane[i][1] = Integer.parseInt(st.nextToken()); // ex) 4 저장
        }

        // x기준으로 오름차순 정렬, 만약 같다면 y기준으로 오름차순 정렬
        Arrays.sort(plane, (o1, o2) -> {
            if (o1[0] == o2[0]) { // x가 같을경우 y기준 오름차순 정렬
                return o1[1] - o2[1];
            }
            return o1[0] - o2[0];
        });

		// 출력문
        StringBuilder sb = new StringBuilder();
        for (int[] plane : planes) {
            sb.append(plane[0]).append(" ").append(plane[1]).append("\n");
        }
        System.out.print(sb);
    }
}
profile
공부가 조은 안드로이드 개발자

1개의 댓글

comment-user-thumbnail
2024년 12월 4일

블로그가 너무 재밌어서 이해도 잘 됩니다ㅋㅋㅋ 잘 보고 갑니다~

답글 달기