[Java] 백준 9063번: 대지

hansung's·2024년 2월 29일
0

문제 url:
대지

문제:

🤔 문제 알아보기


해당 문제를 이해하는데, 이 그림이 가장 좋을 것 같아 가져왔다.
저렇게 점이 찍혔을 때, 해당 점들을 모두 포함할 수 있는 가장 작은 사각형을 만들어라는 게 해당 문제의 요지이다.

그렇다면 우리는 해당 점들에서 x좌표와 y좌표를 구분할 수 있으며,
x좌표의 가장 큰값과 작은값의 차이가 x의 길이가 될 것이고
y좌표의 가장 큰값과 작은값의 차이가 y의 길이가 될 것이다.

이렇게 되면 모든 문제를 이해했다고 볼 수 있다. 그럼 코드를 보며 다시 해석해보겠다.

🐱‍👤 실제 코드


import java.io.*;
import java.util.StringTokenizer;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

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

        int tc = Integer.parseInt(br.readLine());

        List<Integer>x_axis = new ArrayList<>();
        List<Integer>y_axis = new ArrayList<>();

        // 존재할 수 없는 값임을 하기 위해 -1로 초기화
        int x = -1;
        int y = -1;

        for (int i = 0; i < tc; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());

            x_axis.add(Integer.parseInt(st.nextToken()));
            y_axis.add(Integer.parseInt(st.nextToken()));

        }

        br.close();

        //가장 적은 값은 0번째 인덱스에 올 것이며, 가장 큰 값은 size-1인덱스에 위치할 것이다.
        Collections.sort(x_axis);
        Collections.sort(y_axis);

        x = x_axis.get(x_axis.size() -1) - x_axis.get(0);
        y = y_axis.get(y_axis.size() -1) - y_axis.get(0);

        System.out.println(x * y);

    }
}

간략하게 큰틀 먼저 해석하자면, 테스트 케이스(tc)만큼 반복문을 돌 것이며, 돌 때마다 값을 list에 저장한다.
그 후 해당 리스트를 오름차순으로 정렬하는데,
이렇게 되면 가장 큰값은 리스트의 크기 -1의 인덱스에 위치할 것이며,
가장 작은 값은 인덱스 0번째에 위치하게 될 것이다.

그 후 해당 값을 get()메서드로 불러와 뺀 값들을 곱하면 값을 구할 수 있을 것이다.

😊 코드 해석


필자는 머리가 좋지 않다. 그래서 가끔 쉬운코드도 해석하는데 오래 걸리곤 했는데, 그렇기 때문에 간단한 코드라도 코드 해석에 좀 의의를 많이 두는편이다.

코드를 하나씩 하나씩 분해해서 보자.

int tc = Integer.parseInt(br.readLine());

List<Integer>x_axis = new ArrayList<>();
List<Integer>y_axis = new ArrayList<>();

// 존재할 수 없는 값임을 하기 위해 -1로 초기화
int x = -1;
int y = -1;

int tc는 본문에 나와있는 점들의 개수를 의미 한다.

x_axis, y_axis는 나중에 점들의 x값 y값을 저장할 리스트를 생성하였다.
그렇다면 왜 배열을 만들지 않았는가?
음.. 적다보니 배열로 해도 무방하다는 것을 알았다. (그때는 좀 더 편하게 풀자고 ArrayList를 사용했다..)

역시! 이렇게 코드 해석을 하면서 더 나은 방법을 찾을 수 있다.
해당 글을 읽는 분들은 ArrayList보다는 배열로 하는 것이 더 좋을 것이라 생각한다.

int[] x_axis = new int[tc];
int[] y_axis = new int[tc];

더 나은 이유는, 배열이 arraylist보다 색인속도나 메모리면에서 낫기 때문이다.
메모리 면에서 좋은 이유는
-> [Java]ArrayList 구조 및 사용법 이 글을 읽어보면 좋다.

x와 y에 -1을 준 이유는 해당 값은 오늘밤 때려죽어도 나올 수 없는 값이기 때문에 넣은 것이다.


//가장 적은 값은 0번째 인덱스에 올 것이며, 가장 큰 값은 size-1인덱스에 위치할 것이다.
        Collections.sort(x_axis);
        Collections.sort(y_axis);

        x = x_axis.get(x_axis.size() -1) - x_axis.get(0);
        y = y_axis.get(y_axis.size() -1) - y_axis.get(0);

그 다음 코드를 분석하면
Collections.sort를 통해 해당 리스트를 오름차순으로 변경할 수 있다.
※만약 배열로 하신분이 계신다면 아래 코드를 통해 오름차순이 가능하다.

Arrays.sort(x_axis)
Arrays.sort(y_axis)

그 후 주석에도 설명했듯, 최솟값은 인덱스 0번에 최댓값은 크기 -1의 인덱스에 위치한다.
그런 다음 해당 값을 x, y 변수에 저장하여 곱하면 답이 나올 것이다.

🤢 코드 리팩토링


역시나 IT는 무협지와 같다. 필자가 무협지에 요즘 빠짐
자만할수록 성장하지 못하며, 강호에는 늘 강자가 즐비하다.

필자는 본인 스스로 바보라고 생각한다. 그런 이유는 이전에 배웠던 함수를 써먹지 못했기 때문이다.

해당 문제는 Math.min(), Math.max()로 더 쉽게 풀 수 있다.

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

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

            int tc = Integer.parseInt(br.readLine());

            // 좌표가 -10000 이상 10000 이하라고 했기 떄문에 
            // 최솟값은 가장 큰값으로 최댓값은 가장 작은값으로 초기화
            // 이를 통해 무조건 입력받은 값으로 변경될 수 있도록 조치.
            int min_x = 10001;
            int min_y = 10001;
            int max_x = -10001;
            int max_y = -10001;

            for (int i = 0; i < tc; i++) {
                StringTokenizer st = new StringTokenizer(br.readLine());

                int x = Integer.parseInt(st.nextToken());
                int y = Integer.parseInt(st.nextToken());

                min_x = Math.min(min_x, x);
                min_y = Math.min(min_y, y);
                max_x = Math.max(max_x, x);
                max_y = Math.max(max_y, y);

            }

            br.close();

            System.out.println((max_x - min_x) * (max_y - min_y));

        }
    }

해당 코드는 해석 없이 주석으로 대체하겠다.

profile
ABAPER를 꿈꾸는 개발자

0개의 댓글