반응형

자바 코드로 풀어보았다.

 

 

 

 

 

문제 설명

게임개발자인 죠르디는 크레인 인형뽑기 기계를 모바일 게임으로 만들려고 합니다.
죠르디는 게임의 재미를 높이기 위해 화면 구성과 규칙을 다음과 같이 게임 로직에 반영하려고 합니다.

게임 화면은 1 x 1 크기의 칸들로 이루어진 N x N 크기의 정사각 격자이며 위쪽에는 크레인이 있고 오른쪽에는 바구니가 있습니다. (위 그림은 5 x 5 크기의 예시입니다). 각 격자 칸에는 다양한 인형이 들어 있으며 인형이 없는 칸은 빈칸입니다. 모든 인형은 1 x 1 크기의 격자 한 칸을 차지하며 격자의 가장 아래 칸부터 차곡차곡 쌓여 있습니다. 게임 사용자는 크레인을 좌우로 움직여서 멈춘 위치에서 가장 위에 있는 인형을 집어 올릴 수 있습니다. 집어 올린 인형은 바구니에 쌓이게 되는 데, 이때 바구니의 가장 아래 칸부터 인형이 순서대로 쌓이게 됩니다. 다음 그림은 [1번, 5번, 3번] 위치에서 순서대로 인형을 집어 올려 바구니에 담은 모습입니다.

만약 같은 모양의 인형 두 개가 바구니에 연속해서 쌓이게 되면 두 인형은 터뜨려지면서 바구니에서 사라지게 됩니다. 위 상태에서 이어서 [5번] 위치에서 인형을 집어 바구니에 쌓으면 같은 모양 인형 두 개가 없어집니다.

크레인 작동 시 인형이 집어지지 않는 경우는 없으나 만약 인형이 없는 곳에서 크레인을 작동시키는 경우에는 아무런 일도 일어나지 않습니다. 또한 바구니는 모든 인형이 들어갈 수 있을 만큼 충분히 크다고 가정합니다. (그림에서는 화면표시 제약으로 5칸만으로 표현하였음)

게임 화면의 격자의 상태가 담긴 2차원 배열 board와 인형을 집기 위해 크레인을 작동시킨 위치가 담긴 배열 moves가 매개변수로 주어질 때, 크레인을 모두 작동시킨 후 터트려져 사라진 인형의 개수를 return 하도록 solution 함수를 완성해주세요.

[제한사항]

  • board 배열은 2차원 배열로 크기는 5 x 5 이상 30 x 30 이하입니다.
  • board의 각 칸에는 0 이상 100 이하인 정수가 담겨있습니다.
    • 0은 빈 칸을 나타냅니다.
    • 1 ~ 100의 각 숫자는 각기 다른 인형의 모양을 의미하며 같은 숫자는 같은 모양의 인형을 나타냅니다.
  • moves 배열의 크기는 1 이상 1,000 이하입니다.
  • moves 배열 각 원소들의 값은 1 이상이며 board 배열의 가로 크기 이하인 자연수입니다.

입출력 예

board       moves       result

[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4

입출력 예에 대한 설명

입출력 예 #1

인형의 처음 상태는 문제에 주어진 예시와 같습니다. 크레인이 [1, 5, 3, 5, 1, 2, 1, 4] 번 위치에서 차례대로 인형을 집어서 바구니에 옮겨 담은 후, 상태는 아래 그림과 같으며 바구니에 담는 과정에서 터트려져 사라진 인형은 4개 입니다.

 

 

문제 푸는 방법:

자바 import를 잘 해서

ArrayList로 풀 수 있다.

처음에는 ArrayList 사용하는 것이 익숙하지 않았는데,

조금씩 풀어보니까 조금씩 익숙해진다. 화이팅!!

 

정답 코드:

import java.util.*;

class Solution {
    public int solution(int[][] board, int[] moves) {
        int answer = 0;
        int cnt;
        int[] height = new int[board.length];
        for(int i=0; i<height.length; i++){
            cnt = 0;
            for(int j=0; i<height.length; j++){
                if(board[j][i] == 0){
                    cnt++;
                }else{
                    break;
                }
            }
            height[i] = cnt;
        }
        ArrayList<Integer> list = new ArrayList<>();
        
        
        for(int i=0; i<moves.length; i++){
            if(height[moves[i]-1] < height.length){
                list.add(board[height[moves[i]-1]][moves[i]-1]);
                height[moves[i]-1]++;
                if(list.size() >= 2){
                    if(list.get(list.size()-1) == list.get(list.size()-2)){
                        list.remove(list.size()-1);
                        list.remove(list.size()-1);
                        answer += 2;
                    }
                }
            }
            
        }
        
        
        return answer;
    }
}
반응형
반응형

java 코드로 한번 풀어보았다.

 

 

문제 설명

정수 배열 numbers가 주어집니다. numbers에서 서로 다른 인덱스에 있는 두 개의 수를 뽑아 더해서 만들 수 있는 모든 수를 배열에 오름차순으로 담아 return 하도록 solution 함수를 완성해주세요.


제한사항

  • numbers의 길이는 2 이상 100 이하입니다.
    • numbers의 모든 수는 0 이상 100 이하입니다.

입출력 예

numbers      result

[2,1,3,4,1] [2,3,4,5,6,7]
[5,0,2,7] [2,5,7,9,12]

입출력 예 설명

입출력 예 #1

  • 2 = 1 + 1 입니다. (1이 numbers에 두 개 있습니다.)
  • 3 = 2 + 1 입니다.
  • 4 = 1 + 3 입니다.
  • 5 = 1 + 4 = 2 + 3 입니다.
  • 6 = 2 + 4 입니다.
  • 7 = 3 + 4 입니다.
  • 따라서 [2,3,4,5,6,7] 을 return 해야 합니다.

입출력 예 #2

  • 2 = 0 + 2 입니다.
  • 5 = 5 + 0 입니다.
  • 7 = 0 + 7 = 5 + 2 입니다.
  • 9 = 2 + 7 입니다.
  • 12 = 5 + 7 입니다.
  • 따라서 [2,5,7,9,12] 를 return 해야 합니다.

 

 

문제 푸는 방법:

import java.util.*; 이거를 해서

ArrayList랑 HashSet이랑 Collections.sort를 사용하면 된다.

그냥 완전탐색해서 set에 넣어주고 정렬해주면 별다른 에러는 발생하지 않는다.

 

 

정답코드:

import java.util.*;

class Solution {
    public int[] solution(int[] numbers) {
        int[] answer = {};
        HashSet<Integer> temp = new HashSet<>();
        for(int i=0; i<numbers.length; i++){
            for(int j=i+1; j<numbers.length; j++){
                temp.add(numbers[i]+numbers[j]);
            }
        }
        List<Integer> result = new ArrayList(temp);
        Collections.sort(result);
        answer = new int[result.size()];
        for(int i=0; i<result.size(); i++){
            answer[i] = result.get(i);
        }
        return answer;
    }
}

 

 

 

반응형
반응형

 

문제 설명

어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 합니다.

예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있습니다. 이 중 가장 큰 숫자는 94 입니다.

문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어집니다. number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하세요.

제한 조건

  • number는 1자리 이상, 1,000,000자리 이하인 숫자입니다.
  • k는 1 이상 number의 자릿수 미만인 자연수입니다.

입출력 예

numberkreturn

1924 2 94
1231234 3 3234
4177252841 4 775841

 

 

 

 

문제푸는 방법:

첫번째 방법: 처음에 문자열을 slice해서 접근하는 방법으로 풀어보았다. 그런데 8,10번 케이스에서 자꾸 시간초과 에러가 발생했다.

두번째 방법(정답): 결국 구글링을 통해 스택을 이용해서 풀었다. 

1) 스택에 하나씩 집어넣는다.

2) 큰 녀석이 들어오면 그 동안 쌓인 스택에서 하나씩 비교한 후 작은 놈을 제거해준다.

3) 제거해줄때마다 count + 1 해준다.

4) count == k 가 된다면 남아있는 아직 넣지 않은 number에 대한 값들을 stack에 전부 넣어준다.

5) 그리고 stack에 있는 값들중 len(number)-k 만큼만 출력해준다.

6) 마지막에 "".join(stack[:len(num)-k])를 반환해준다.

그 이유는 12번 케이스같은 경우 입력값 number = "54321" / k = 4로 테스트해보면,

stack = ["5","4","3","2","1"] 이 들어있다.

그래서 1개만 출력을 해주어야 한다.

 

정답코드:

def solution(number, k):
    answer = ''
    num = list(number) 
    stack = [num[0]] 
    count = 0
    
    for i in range(1,len(num)):
        if count == k:
            stack = stack + num[i:]
            break
        
        stack.append(num[i])
        if stack[-1] > stack[-2]:
            while len(stack) != 1 and stack[-1] > stack[-2] and count < k:
                del stack[-2]
                count += 1
    return "".join(stack[:len(num)-k])

 

참조: 나도 첫번째 방법으로 하다가 구글링해서 풀었다.ㅠㅠ

kdgt-programmer.tistory.com/5?category=1121942

 

[프로그래머스] 큰 수 만들기 - 그리디 greedy | 스택 Stack (python) (2)

5. 두번째 풀이 스택을 이용하여 풀이가 가능하다. for문을 이용하여 스택에 숫자들을 넣으며 다음 조건들을 만족시켜주면 된다. 숫자를 넣었을 때 직전에 넣은 숫자가 더 작은 경우 자리를 바꾼

kdgt-programmer.tistory.com

blog.naver.com/PostView.nhn?blogId=lhaayyy&logNo=221889005763

 

[프로그래머스/c++] 큰 수 만들기 (+12번 테스트케이스)

프로그래머스 level2. 큰 수 만들기​▶ 풀이 방법 엄~~~청 고민하다가 생각보다 단순하게 풀었는데 string...

blog.naver.com

 

반응형
반응형

 

 

문제 설명

두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.

1. 한 번에 한 개의 알파벳만 바꿀 수 있습니다. 2. words에 있는 단어로만 변환할 수 있습니다.

예를 들어 begin이 hit, target가 cog, words가 [hot,dot,dog,lot,log,cog]라면 hit -> hot -> dot -> dog -> cog와 같이 4단계를 거쳐 변환할 수 있습니다.

두 개의 단어 begin, target과 단어의 집합 words가 매개변수로 주어질 때, 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 각 단어는 알파벳 소문자로만 이루어져 있습니다.
  • 각 단어의 길이는 3 이상 10 이하이며 모든 단어의 길이는 같습니다.
  • words에는 3개 이상 50개 이하의 단어가 있으며 중복되는 단어는 없습니다.
  • begin과 target은 같지 않습니다.
  • 변환할 수 없는 경우에는 0를 return 합니다.

입출력 예

begin     target     words     return

hit cog [hot, dot, dog, lot, log, cog] 4
hit cog [hot, dot, dog, lot, log] 0

입출력 예 설명

예제 #1
문제에 나온 예와 같습니다.

예제 #2
target인 cog는 words 안에 없기 때문에 변환할 수 없습니다.

 

 

 

문제 푸는 방법:

최단경로를 찾는 문제이다.

힌트는 한번에 1개의 단어만 변할 수 있다고 하는 부분에서 edge라고 생각하여 graph를 그릴 수 있다.

그래프를 그린 후에 target 노드까지 가는 최단 경로를 BFS 알고리즘을 통해 구해주면 된다.

 

정답 코드:

from collections import defaultdict

def solution(begin, target, words):
    if target not in words:
        return 0
    answer = 0
    graph = defaultdict(set)
    words.append(begin)
    for i in range(len(words)-1):
        for j in range(i+1,len(words)):
            if is_convert(words[i],words[j]):
                graph[words[i]].add(words[j])
                graph[words[j]].add(words[i])
    
    result = BFS(graph,begin)
    return result[target]

def BFS(graph, start):
    visited = {}
    queue = [(start,0)]
    
    while queue:
        cur = queue.pop(0)
        if cur[0] not in visited:
            visited[cur[0]] = cur[1]
            arr = set(graph[cur[0]]) - set(visited)
            queue.extend([(i,cur[1]+1) for i in arr])
    return visited

def is_convert(begin,target):
    cnt = 0
    for x,y in zip(begin,target):
        if x!=y:
            cnt += 1
    if cnt == 1:
        return True
    else:
        return False
반응형
반응형

 

 

 

문제 설명

n명이 입국심사를 위해 줄을 서서 기다리고 있습니다. 각 입국심사대에 있는 심사관마다 심사하는데 걸리는 시간은 다릅니다.

처음에 모든 심사대는 비어있습니다. 한 심사대에서는 동시에 한 명만 심사를 할 수 있습니다. 가장 앞에 서 있는 사람은 비어 있는 심사대로 가서 심사를 받을 수 있습니다. 하지만 더 빨리 끝나는 심사대가 있으면 기다렸다가 그곳으로 가서 심사를 받을 수도 있습니다.

모든 사람이 심사를 받는데 걸리는 시간을 최소로 하고 싶습니다.

입국심사를 기다리는 사람 수 n, 각 심사관이 한 명을 심사하는데 걸리는 시간이 담긴 배열 times가 매개변수로 주어질 때, 모든 사람이 심사를 받는데 걸리는 시간의 최솟값을 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 입국심사를 기다리는 사람은 1명 이상 1,000,000,000명 이하입니다.
  • 각 심사관이 한 명을 심사하는데 걸리는 시간은 1분 이상 1,000,000,000분 이하입니다.
  • 심사관은 1명 이상 100,000명 이하입니다.

입출력 예

ntimes     return

6 [7, 10] 28

입출력 예 설명

가장 첫 두 사람은 바로 심사를 받으러 갑니다.

7분이 되었을 때, 첫 번째 심사대가 비고 3번째 사람이 심사를 받습니다.

10분이 되었을 때, 두 번째 심사대가 비고 4번째 사람이 심사를 받습니다.

14분이 되었을 때, 첫 번째 심사대가 비고 5번째 사람이 심사를 받습니다.

20분이 되었을 때, 두 번째 심사대가 비지만 6번째 사람이 그곳에서 심사를 받지 않고 1분을 더 기다린 후에 첫 번째 심사대에서 심사를 받으면 28분에 모든 사람의 심사가 끝납니다.

출처

※ 공지 - 2019년 9월 4일 문제에 새로운 테스트 케이스를 추가하였습니다. 도움을 주신 weaver9651 님께 감사드립니다.

 

 

문제 푸는 방법:

이진 탐색을 사용하여 문제를 푼다.

1분 부터 (가장 오래걸리는 심사관의 입국 심사 시간)*n 까지 범위를 두고,

mid = (left + right) / 2

mid라는 시간에서 각 심사관이 몇 명을 심사볼 수 있는지 isPassed 라는 메소드를 통해 확인

isPassed -> true 이면 현재 시간(mid)에 사람들이 모두 심사를 볼 수 있음(하지만 우리는 최솟값을 얻기 위한 것이니, left <= right일때까지 반복 true이면 right = mid -1로 더 줄여나감

isPassed -> false이면 현재 시간(mid)에 사람들이 모두 심사를 볼 수 있는 건 아님 => left = mid+1 로 현재시간을 더 늘려보기로 함

 

해당 과정을 left <= right 일때까지 반복하고 return 한다.

 

정답 코드(Java):

import java.util.*;

class Solution {
    public long solution(int n, int[] times) {
        Arrays.sort(times);
        return BinarySearch(times,n,times[times.length - 1]);
    }
    
    long BinarySearch(int[] times, int n, long max){
        long left = 1, right = max * n;
        long mid = 0;
        long ans = Long.MAX_VALUE;
        
        while (left <= right){
            mid = (left+right)/2;
            
            if (isPassed(times,n,mid)){
                ans = ans > mid ? mid : ans;
                right = mid - 1;
            }else{
                left = mid + 1;
            }
        }
        return ans;
    }
    
    boolean isPassed(int[] times, int n, long mid){
        long amount = 0;
        
        for(int i=0; i<times.length; ++i){
            amount += mid/times[i];
        }
        if (amount>=n) return true;
        else return false;
    }
}

 

 

 

반응형
반응형

 

 

문제 설명

n개의 음이 아닌 정수가 있습니다. 이 수를 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.

-1+1+1+1+1 = 3

+1-1+1+1+1 = 3

+1+1-1+1+1 = 3

+1+1+1-1+1 = 3

+1+1+1+1-1 = 3

사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 주어지는 숫자의 개수는 2개 이상 20개 이하입니다.
  • 각 숫자는 1 이상 50 이하인 자연수입니다.
  • 타겟 넘버는 1 이상 1000 이하인 자연수입니다.

입출력 예

numbers    target    return

[1, 1, 1, 1, 1] 3 5

입출력 예 설명

문제에 나온 예와 같습니다.

 

 

문제 푸는 방법:

모든 숫자에 +,-를 다 해보는 수밖에 없다.

+1 +1 +1 (?) (?) 이렇게 앞에서 3이 된다고 해도, 뒤에 값이 0이 된다는 보장이 없기 때문이다.

그래서 각 위치에 +/-를 해주어야 한다.

예제에 있어서는 2**5 번의 성능이 발생한다.

 

평균적으로 2**len(numbers) 만큼의 연산을 해야하는 것이다.

 

일단 DFS 로 풀 수 있다.

각 자리수로 들어가면서 해당 값을 +/- 연산을 모두 수행하는 것이다.

그리고 마지막 idx일때, 해당 값이 target과 같다면 result 라는 리스트에 1을 append해주고, target과 다르다면 0을 append 해준다.

==> 나중에 sum(result) 하면 1의 개수를 알 수 있다.

 

아래의 코드에서는 DFS는 재귀로 구현하였다.

정답 코드:

def solution(numbers, target):
    result = []
    DFS(numbers,0,0,target,result)
    return sum(result)

def DFS(arr,idx,current,target,result):
    if idx == len(arr):
        if current == target:
            return result.append(1)
        else:
            return result.append(0)
    DFS(arr,idx+1,current+arr[idx],target,result)
    DFS(arr,idx+1,current-arr[idx],target,result)
    return

 

 

 

반응형
반응형

 

 

문제 설명

n명의 권투선수가 권투 대회에 참여했고 각각 1번부터 n번까지 번호를 받았습니다. 권투 경기는 1대1 방식으로 진행이 되고, 만약 A 선수가 B 선수보다 실력이 좋다면 A 선수는 B 선수를 항상 이깁니다. 심판은 주어진 경기 결과를 가지고 선수들의 순위를 매기려 합니다. 하지만 몇몇 경기 결과를 분실하여 정확하게 순위를 매길 수 없습니다.

선수의 수 n, 경기 결과를 담은 2차원 배열 results가 매개변수로 주어질 때 정확하게 순위를 매길 수 있는 선수의 수를 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 선수의 수는 1명 이상 100명 이하입니다.
  • 경기 결과는 1개 이상 4,500개 이하입니다.
  • results 배열 각 행 [A, B]는 A 선수가 B 선수를 이겼다는 의미입니다.
  • 모든 경기 결과에는 모순이 없습니다.

입출력 예

n     results     return

5 [[4, 3], [4, 2], [3, 2], [1, 2], [2, 5]] 2

입출력 예 설명

2번 선수는 [1, 3, 4] 선수에게 패배했고 5번 선수에게 승리했기 때문에 4위입니다.
5번 선수는 4위인 2번 선수에게 패배했기 때문에 5위입니다.

 

 

 

문제푸는 방법:

1. 그래프를 사용해서 푸는 문제이다.

2. 대신 순서가 있다. 이긴 방향 그래프 / 진 방향 그래프

3. 이긴 방향 그래프를 통해 나보다 아래있는 노드의 '개수'를 파악한다.(최단 경로 이런 문제 아님)

4. 진 방향 그래프를 탐색하면서 나보다 위에 있는 노드의 '개수'를 파악한다.

5. 3번과 4번의 결과가 n-1개여야지 순서가 제대로 정해진 것이다.

6. 1~n까지 5에 해당하는 경우 result +=1 해준다.

7. result를 반환해준다.

 

 

정답 코드:

 

def solution(n, results):
    arr = {}
    arr2 = {}
    for i in results:
        if i[0] not in arr:
            arr[i[0]] = [i[1]]
        else:
            arr[i[0]].append(i[1])
        if i[1] not in arr2:
            arr2[i[1]] = [i[0]]
        else:
            arr2[i[1]].append(i[0])
    answer = 0
    for i in range(1,n+1):
        if bfs(arr,i) + bfs(arr2,i) == n-1:
            answer += 1
    return answer

def bfs(graph,start):
    queue = [[start,0]]
    visited = []
    a = -1
    while queue:
        current = queue.pop(0)
        if current[0] not in visited:
            a += 1
            visited.append(current[0])
            if current[0] in graph:
                arr = set(graph[current[0]]) - set(visited)
                queue.extend([[i,current[1]+1] for i in arr])
    return a

 

 

코드 최적화

as-is:

11줄의 코드를

arr = {}
arr2 = {}
for i in results:
    if i[0] not in arr:
        arr[i[0]] = [i[1]]
    else:
        arr[i[0]].append(i[1])
    if i[1] not in arr2:
        arr2[i[1]] = [i[0]]
    else:
        arr2[i[1]].append(i[0])

to-be:

6줄로 간결하게 만들어준다.

from collections import defaultdict
~~~~~~~

arr = defaultdict(set)
arr2 = defaultdict(set)
for i in results:
    arr[i[0]].add(i[1])
    arr2[i[1]].add(i[0])

 

 

 

 

프로그래머스를  풀면서 또 하나 느낀 점은 반드시 효율적인 코드를 짜는 것보다는 

정확한 방법이 생각나면 일단 도전해보는 것이다.

도전해보면 의외로 프로그래머스에서 정확도만 채점하는 경우도 있기 때문이다.(이 문제같은 경우 그렇다.)

 

 

 

 

 

NHN 코딩테스트를 대비하여 Java 코드로도 풀어보았다.

푸는 방식은 위의 파이썬 설명과 같다.

import java.util.*;

class Solution {
    public int solution(int n, int[][] results) {
        int answer = 0;
        ArrayList<ArrayList<Integer>> win = new ArrayList<ArrayList<Integer>>();
        ArrayList<ArrayList<Integer>> lose = new ArrayList<ArrayList<Integer>>();
        for(int i=0; i<n+1; i++){
            win.add(new ArrayList<Integer>());
            lose.add(new ArrayList<Integer>());
        }
        for(int[] i: results){
            int a = i[0];
            int b = i[1];
            win.get(a).add(b);
            lose.get(b).add(a);
        }
        int ans = 0;
        for(int i=1; i<n+1; i++){
            if(BFS(win,i,n)+BFS(lose,i,n) == n-1){
                ans++;
            }
        }
        return ans;
    }
    int BFS(ArrayList<ArrayList<Integer>> graph, int start, int n){
        boolean[] visited = new boolean[n+1];
        visited[start] = true;
        Queue<Integer> q = new LinkedList<Integer>();
        q.add(start);
        int a = -1;
        while(!q.isEmpty()){
            int cur = q.poll();
            a++;
            for(int i:graph.get(cur)){
                if(!visited[i]){
                    visited[i] = true;
                    q.add(i);
                }
            }
        }
        return a;
    }
}
반응형
반응형

 

 

 

 

문제 설명

Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 노란색으로 칠해져 있고 테두리 1줄은 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다.

Leo는 집으로 돌아와서 아까 본 카펫의 노란색과 갈색으로 색칠된 격자의 개수는 기억했지만, 전체 카펫의 크기는 기억하지 못했습니다.

Leo가 본 카펫에서 갈색 격자의 수 brown, 노란색 격자의 수 yellow가 매개변수로 주어질 때 카펫의 가로, 세로 크기를 순서대로 배열에 담아 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 갈색 격자의 수 brown은 8 이상 5,000 이하인 자연수입니다.
  • 노란색 격자의 수 yellow는 1 이상 2,000,000 이하인 자연수입니다.
  • 카펫의 가로 길이는 세로 길이와 같거나, 세로 길이보다 깁니다.

입출력 예

brown    yellow    return

10 2 [4, 3]
8 1 [3, 3]
24 24 [8, 6]

출처

※ 공지 - 2020년 2월 3일 테스트케이스가 추가되었습니다.
※ 공지 - 2020년 5월 11일 웹접근성을 고려하여 빨간색을 노란색으로 수정하였습니다.

 

 

 

문제 푸는 방식:

완전 탐색 알고리즘을 사용하여 무식하게 for문을 통해 모든 경우를 살펴봐야한다.

실제로 네이버에서 면접을 볼때 완전탐색을 요하는 문제를 물어보았다.

 

우선 yellow의 값이 될 수 있는 가로*세로의 모든 경우을 고르고

모든 경우에서 brown의 개수가 충족되는 것을 찾아내었다.

 

정답 코드는 아래와 같다.

def solution(brown, yellow):
    answer = []
    a = measure(yellow)
    for i in a:
        if (i[0]+2)*2+(i[1]*2) == brown:
            return [i[0]+2,i[1]+2]
    
    return answer

def measure(num):
    i = 1
    result = []
    while i*i <= num:
        if num%i==0:
            result.append([num//i,i])
        i += 1
    return result
반응형

+ Recent posts