알고리즘

99클럽 코테 스터디 9일차 TIL 카펫

ernest45 2024. 5. 28. 23:11

https://school.programmers.co.kr/learn/courses/30/lessons/42842

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

1. 문제 해설 및 접근법

 

 

중앙에 노란색으로 색칠되어 있고 겉엔 갈색으로 감싼 구조의 카펫이 있다.

카펫의 크기를 기억하지 못하고 노랑타일의 수, 갈색 타일의 수만 알 때 가로와 세로를 반환해라

 

갈색 격자의 수 brown은 8 이상 5,000 이하인 자연수입니다.

노란색 격자의 수 yellow는 1 이상 2,000,000 이하인 자연수입니다.

카펫의 가로 길이는 세로 길이와 같거나, 세로 길이보다 깁니다.

 

가로가 기니까 약수들을 찾고 o1(가로) 약수가 커지거나 같아질 (제곱근까지만 구해도 되긴 하겠다)

 

 

2. (틀린) 풀이법 

 

class Solution {
    public int[] solution(int brown, int yellow) {
        int[] answer = new int[2];

        int size = brown + yellow;

        for (int i = 2; i < size; i++) {

            if (size % i == 0) { // 제곱근까지 할 지  ? 그냥 size는 안들어오게 하면 될듯

                int j = size / i;

                if (i >= j) {

                    answer[0] = i;
                    answer[1] = j;
                    break;
                }

            }

        }

        return answer;
    }
}

 

 

틀린 풀이라서 약간만 설명 하자면

 

 

brown 과 yellow를 합쳐서 size에 담아주고

 

 

약수들을 찾는다.

 

i가 가로라면, j를 세로로 선언하고 규칙에서 i보다 j가 같거나 크기 때문에

 

 

 

적용해주면 끝날줄 알았으나 ?

 

 

어디서 틀렸는지 몰라서 찾아보니 

 

brown 18과  yellow 6이 들어온다면 18 + 6 = 24

24에서 약수들을 찾고, 더 커지면 return

 

[i = 1, j = 24] 

[i = 2, j = 12]

[i = 3, j = 8]

[i = 4, j = 6]

[i = 6, j = 4]

...

...

 

에서 걸려 6, 4라고 생각했는데 정답은 다음 수인 [i = 8, j = 3]이다

 

 

여기서 yellow를 기준으로 풀어보려고 

볼 필요도 없다

 

열심히 짜고 보니 내가 yellow의 수를 착각해서 반복적인 코드를 계속 추가했다..

(일정이 있어 잠을 못 잤더니 엄청 피곤해서 진짜 헛 것이 보였나보다.. 시간 엄청 날림)

 

 

 

 

3.  해답

 

private int[] solution(int brown, int yellow) {
    int[] answer = new int[2];


    int size = brown + yellow;

    for (int row = 3; row < size; row++) {


        if (size % row == 0) { // 제곱근까지 할 지  ? 그냥 size는 안들어오게 하면 될듯

            int column = size / row;

            if (row == column) { //row와 column이 같다는 건 정 사각 안에 정사각이라 됨

                answer[0] = row;
                answer[1] = column;

                return answer;
            }
          if (row > column && column >= 3 ) {



                    int middle = (column - 2) * (row - 2);

                    if (middle == yellow) {
                        answer[0] = row;
                        answer[1] = column;

                        return answer;
                }
            }
        }
    }

    return answer;
    
}

 

전체 풀이

 

 

 

3-1 for문

 

size는 마찬가지로 총 갯수이고,

3부터 시작하는 이유는 최소 3이여야만 중간에 위치할 수 있기 때문

 

size를 row로 나눴을 때 나눠진다면 size의 약수이고, size의 약수의 나머지 수도 저장

 

 

 

 

만약 약수이고 두 수가 같다면 가운데 정사각형으로 칠해져 있기에 바로 return

 

 

 

if문 조건으로는 일단 더 상위 조건문에서 row는 size의 약수이고,

가로가 세로보다 커야하고, clumn은 3 이하면 노란 중안 밖 테두리에 갈색을 두를 수 없다.

 

 

즉 입력으로 들어온 yellow의 개수만큼 노란색 카펫이 가운데에 위치할 수 있는지 확인해야 한다.

 

 

중앙 값으로 오려면 (가로 -2) * (세로 -2)가 yellow랑 동일하다면 저장해주고 return;

 

 

 

 

4. 마무리

 

 

엄청 간단한 문제인데, 문제가 헷갈리기도 했고 너무 피곤해서 잘못 생각한 것들이 나비효과처럼

토네이도를 몰고왔다..

 

하나만 잘못 이해하면 몰라 싹 다 조금씩 틀리다 보니, 그냥 bfs 쓸까 ? 아님 다 집어 넣어버릴까 고민도 좀 했다..

 

앞으로 피곤할 땐 조금 쉬고 해야겠다 ㅠㅠ