<문제 설명>
Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 빨간색으로 칠해져 있고 모서리는 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다.
Leo는 집으로 돌아와서 아까 본 카펫의 빨간색과 갈색으로 색칠된 격자의 개수는 기억했지만, 전체 카펫의 크기는 기억하지 못했습니다.
Leo가 본 카펫에서 갈색 격자의 수 brown, 빨간색 격자의 수 red가 매개변수로 주어질 때 카펫의 가로, 세로 크기를 순서대로 배열에 담아 return 하도록 solution 함수를 작성해주세요.
제한사항
- 갈색 격자의 수 brown은 8 이상 5,000 이하인 자연수입니다.
- 빨간색 격자의 수 red는 1 이상 2,000,000 이하인 자연수입니다.
- 카펫의 가로 길이는 세로 길이와 같거나, 세로 길이보다 깁니다.
<입출력 예>
brown | red | return |
10 | 2 | [4, 3] |
8 | 1 | [3, 3] |
24 | 24 | [8, 6] |
<내 풀이>
처음 문제를 보고 규칙을 찾아보았다.
가로길이를 x, 세로길이를 y라고 했을 때
갈색격자는 모서리에만 해당하고 있기 때문에 2*(x+y)-4 = brown 이고
전체 타일 개수는 brown+red이기도 하며, 가로길이*세로길이 일 것이다.
전체 타일개수를 두 정수로 나뉘게 인수분해해서 만들 수 있는 경우를 하나씩
2*(x+y)-4 == brown인지 확인해 맞으면 정답으로 반환하게 하는 식으로 처음 구현했다.
<첫 코드 - 효율성테스트 탈락>
class FirstSolution {
public int[] solution(int brown, int red) {
int total = brown+red;
int[] answer = new int[2];
int x;
int y;
int pre_x = 1;
int div=2;
while(true){
if(total%div==0){
pre_x = pre_x*div;
total=total/div;
if(2*pre_x+2*total-4 == brown){
answer[0] = pre_x;
answer[1] = total;
break;
}
}
else{
div++;
}
}
return answer;
}
}
<다른 사람 코드>
(출처: https://ju-nam2.tistory.com/82)
red를 기준으로 탐색,
red/2 + 1까지만 하면 된다. (직사각형이기 때문에)
brown의 수가 red_가로*2 + red_세로*2 + 4와 같으면 for문을 멈추면 된다.
또한 가로의 길이가 세로의 길이보다 길거나 같으므로 큰 쪽을 가로로, 작은 쪽을 세로로 두면 된다.
class secondSolution {
public int[] solution(int brown, int red) {
int width = 0;
int height = 0;
for(int i=1; i<=red/2+1; i++) {
width = i;
height = (red%i==0) ? red/i:red/i+1;
if(2*width + 2*height + 4 == brown) break;
}
int[] answer = {Math.max(width, height)+2, Math.min(width, height)+2};
return answer;
}
}
굳이 brown을 기준으로 두지않고 red를 기준으로 더 간단하게 구할 수 있었다
'알고리즘 > 문제풀이' 카테고리의 다른 글
[프로그래머스] 주식 가격 문제 (0) | 2020.01.23 |
---|---|
[프로그래머스] H-Index 문제 (0) | 2020.01.22 |
[프로그래머스] 숫자야구 문제 (0) | 2020.01.20 |
[프로그래머스] 모의고사 문제 (0) | 2020.01.18 |
[프로그래머스] 소수찾기 문제 (0) | 2020.01.17 |