문제 설명

무인도에 갇힌 사람들을 구명보트를 이용하여 구출하려고 합니다. 구명보트는 작아서 한 번에 최대 2명씩 밖에 탈 수 없고, 무게 제한도 있습니다.
예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 50kg]이고 구명보트의 무게 제한이 100kg이라면 2번째 사람과 4번째 사람은 같이 탈 수 있지만 1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을 초과하여 같이 탈 수 없습니다.
구명보트를 최대한 적게 사용하여 모든 사람을 구출하려고 합니다.
사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때, 모든 사람을 구출하기 위해 필요한 구명보트 개수의 최솟값을 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 무인도에 갇힌 사람은 1명 이상 50,000명 이하입니다.
  • 각 사람의 몸무게는 40kg 이상 240kg 이하입니다.
  • 구명보트의 무게 제한은 40kg 이상 240kg 이하입니다.
  • 구명보트의 무게 제한은 항상 사람들의 몸무게 중 최댓값보다 크게 주어지므로 사람들을 구출할 수 없는 경우는 없습니다.

입출력 예

people limit return
[70, 50, 80, 50] 100 3
[70, 80, 50] 100 3

 


내 문제풀이

1. 몸무게 무거운 순, 가벼운 순으로 정렬한 두 개의 리스트를 생성한다.

2. 전체 사람의 수보다 구출된 사람의 수(live)가 더 작을 동안 반복문을 수행한다.

3. 가장 무거운 사람 + 가장 가벼운사람 이 구명보트의 무게 제한보다 작거나 같다면, 구출된 사람의 수를 +2하고, 구명보트 개수(answer), 몸무게 무거운 순 리스트(rev_people), 몸무게 가벼운 순 리스트(people)의 index 모두 +1 해준다.

4. 3번의 경우에 맞지 않다면, 가장 무거운 사람만 구출하며, 구출된 사람의 수, 구명보트 개수(answer), 몸무게 무거운 순 리스트(rev_people)의 index 모두 +1 해준다.

내 코드 - 파이썬

def solution(people, limit):
    answer = 0
    live = 0 # 구출된 사람 수
    
    rev_people = sorted(people, reverse=True) # 몸무게 무거운 순
    people.sort() # 몸무게 가벼운 순
    big = 0
    small = 0
    
    while(live < len(people)):
        if rev_people[big] + people[small] <= limit:
            live += 2
            answer, big, small = answer+1, big+1, small+1
        else :
            live, answer, big = live+1, answer+1, big+1
            
    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의 자릿수 미만인 자연수입니다.

입출력 예

number k return
1924 2 94
1231234 3 3234
4177252841 4 775841

 


내 문제풀이

1. 완성된 수를 넣을 리스트(new_list)에 number의 첫 원소 수를 넣는다.

2. number의 길이만큼 도는 반복문 내부에서 while문을 수행한다. k, new_list가 존재하고 new_list의 가장 마지막 원소가 number의 현재 원소 값보다 작은 경우에 수행한다. 이 경우에 new_list의 마지막 원소를 제거하고, k-1을 해준다. 

3. while문이 끝나면 number의 현재 원소 값을 new_list에 추가한다.

4. 내가 생각한 반환하는 경우의 수는 총 3가지이다. 

4-1. 만약 for문이 다 끝나기 전, k가 0이 되었을 때 현재 number 원소의 인덱스 값을 answer에 저장하고 반복문을 나온다.이 경우는 뺄 수 있는 만큼의 수를 이미 다 뺸 것이기 때문에 number에 남은 뒤의 숫자들을 new_list에 추가해주고 new_list를 반환한다.

4-2. 만약 위의 while문에서 계속 new_list의 가장 마지막 원소가 number의 현재 원소 값보다 큰 경우, while문이 실행되지 않고 new_list에 number의 원소만 append할 수 있다. 따라서 for문이 다 끝났지만 k가 0이 아닌 경우, new_list의 원소는 이미 가장 큰 수의 조건은 만족하고 있으므로 [:-k]의 인덱스 슬라이싱을 사용한다. 따라서 남은 k만큼의 뒷 부분 숫자를 잘라서 반환한다.

4-3. 위의 for문에서 k가 0이 되었지만 그 전에 for문이 끝난 경우, new_list가 깔끔하게 완성된 것이다. 따라서 그대로 new_list를 반환한다.

 

내 코드 - 파이썬

def solution(number, k):
    answer = 0
    new_list = [number[0]]
        
    for n in range(1, len(number)):
        if k == 0:
            answer = n
            break
        
        while k and new_list and new_list[-1] < number[n]:
            new_list.pop()
            k-=1
        new_list.append(number[n])
            
    # 위의 while문에서 new_list[-1]보다 작은 수만 들어와서 계속 append 하고 k가 남은 상황
    if k!=0:
        return ''.join(new_list[:-k])
    
    # 위의 for문을 다 돌고 나온 상황(k==0 조건문에 걸리기 전에) -> 깔끔하게 new_list 완성
    if answer == 0:
        return ''.join(new_list)
    
    # 위의 for문을 다 돌기 전 k==0에 걸린 상황
    new_list.append(number[answer::])     
    return ''.join(new_list)

문제 설명

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.

전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 전체 학생의 수는 2명 이상 30명 이하입니다.
  • 체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
  • 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.

입출력 예

n lost reserve return
5 [2, 4] [1, 3, 5] 5
5 [2, 4] [3] 4
3 [3] [1] 2

 


내 문제풀이

1. 여벌 체육복을 가져온 학생이 체육복을 도난당한 경우, 해당 학생을 reserve, lost 리스트에서 모두 삭제한다. 또한 이를 고려한, 처음부터 본인의 체육복으로 수업을 들을 수 있는 학생 수를 계산한다.

2. 1번에서 새로 생성한 new_lost, new_reserve를 가지고 반복문을 수행한다. 체육복이 없는 학생을 보며, 먼저 바로 뒤 학생이 여벌 체육복을 가지고 있는지 확인하고 이후에는 바로 앞 학생이 여벌 체육복을 가지고 있는지 확인한다. 
이 경우에 수업에 참여할 수 있는 학생의 수(answer)+1을 하고, 여벌 체육복을 빌려 줄 수 있는 학생을 new_reserve에서 삭제한다.

내 코드 - 파이썬

def solution(n, lost, reserve):
  
    new_reserve = set(reserve)-set(lost)
    new_lost = set(lost)-set(reserve)
            
     # 초기 체육복 있는 학생
    answer = n-len(new_lost)
    
    for idx in new_lost:
        if idx+1 in new_reserve:
                answer+=1
                new_reserve.remove(idx+1)
        elif idx-1 in new_reserve:
            answer+=1
            new_reserve.remove(idx-1)
    
    return answer

문제 설명

한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.
각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.

제한사항

  • numbers는 길이 1 이상 7 이하인 문자열입니다.
  • numbers는 0~9까지 숫자만으로 이루어져 있습니다.
  • 013은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.

입출력 예

numbers return
17 3
011 2

 


내 문제풀이

1. permutations()를 사용해서 numbers에서 나올 수 있는 모든 조합의 수를 계산 후 리스트에 추가하고 set()으로 중복을 제거한다.
2. 생성한 리스트를 반복문을 돌며 소수인지 판별한다. 소수이면 answer값을 +1 해준다.

itertools.permutations

permutations(값, 만들 조합의 자릿수) 를 하면 tuple 형태로 쪼개어 수 조합을 만들어준다.

예를 들어 permutations('123', 2)인 경우 [('1', '2'), ('1', '3'), ('2', '3')]가 반환된다.

내 코드 - 파이썬

from itertools import permutations

def solution(numbers):
    answer = 0
    num_list = []
    for i in range(1, len(numbers)+1):
        per_list = list(permutations(numbers, i))
        for j in per_list:
            num_list.append(''.join(j))
    num_list = set([int(x) for x in num_list])
    
    for num in num_list:
        is_prime = 1
        if num<2:
            continue
        for i in range(2, num):
            if(num%i==0):
                is_prime = 0
                break
        if(is_prime): answer+=1
        
    return answer

문제 설명

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]

 


내 문제풀이

1. 갈색의 세로 (짧은 쪽) 최소 길이는 3이다. 따라서 테두리 세로 길이를 3부터 1씩 증가시키며 반복문을 수행한다.
2. 노란색(가운데)의 격자 수(넓이)는 (갈색 가로 길이-2)*(갈색 세로 길이-2)이다. 이 때 갈색 가로 길이는 (총 갈색 격자 수//2 - 갈색 세로 길이 + 2)이다. +2가 필요한 이유는 양 끝의 세로 격자 1개씩 추가해야 하기 때문이다. 
3. 반복문을 수행하다가 (갈색 가로 길이-2)*(갈색 세로 길이-2) == 노란색의 넓이(격자 수) 인 경우 갈색의 가로 길이, 갈색의 세로 길이 배열을 반환한다.

내 코드 - 파이썬

def solution(brown, yellow):
    answer = []
    
    for col in range(3, brown//2):
        if (col-2)*(brown//2-col) == yellow:
            return [brown//2-col+2, col]
    

문제 설명

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다.
1번 수포자가 찍는 방식: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
2번 수포자가 찍는 방식: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ...
3번 수포자가 찍는 방식: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...
1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution 함수를 작성해주세요.

제한 조건

  • 시험은 최대 10,000 문제로 구성되어있습니다.
  • 문제의 정답은 1, 2, 3, 4, 5중 하나입니다.
  • 가장 높은 점수를 받은 사람이 여럿일 경우, return하는 값을 오름차순 정렬해주세요.

입출력 예

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

 


내 문제풀이

1. 1번, 2번, 3번 수포자의 문제 푸는 방식을 반복 없이 list에 저장한다.
2. answers 길이 만큼 반복문을 돌며 1번, 2번, 3번 수포자의 찍은 번호와 정답 번호를 비교한다. 이 때 같으면(정답) grade 리스트에 +1을 한다. grade 리스트의 index(n-1)는 n번 수포자를 의미한다.
3. grade의 가장 큰 값을 구한 후 해당 정답 갯수와 일치하는 수포자를 answer 리스트에 추가하여 반환한다.

내 코드 - 파이썬

def solution(answers):
    answer = []
    grade = [0]*3
    first = [1,2,3,4,5]
    second = [2, 1, 2, 3, 2, 4, 2, 5]
    third = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    
    for idx in range(0, len(answers)):
        if answers[idx] == first[idx%5]:
            grade[0] += 1
        if answers[idx] == second[idx%8]:
            grade[1] += 1
        if answers[idx] == third[idx%10]:
            grade[2] += 1
    
    max_grade = max(grade)
    for idx in range(0, 3):
        if grade[idx] == max_grade:
            answer.append(idx+1)  
    
    return answer

문제 설명

H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 위키백과1에 따르면, H-Index는 다음과 같이 구합니다.
어떤 과학자가 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.
어떤 과학자가 발표한 논문의 인용 횟수를 담은 배열 citations가 매개변수로 주어질 때, 이 과학자의 H-Index를 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 과학자가 발표한 논문의 수는 1편 이상 1,000편 이하입니다.
  • 논문별 인용 횟수는 0회 이상 10,000회 이하입니다.

입출력 예

citations return
[3, 0, 6, 1, 5] 3

 


내 문제풀이

1. citations를 오름차순 정렬한다.
2. citiations의 값들을 현재 값 뒤에 있는 원소 갯수(현재 값보다 크거나 같은 수의 갯수)와 비교한다. 현재 값이 뒤에 있는 원소 갯수보다 큰 경우 "h번 이상 인용된 논문이 h편 이상" 조건이 만족한다.
3. 이 때 h 값인 뒤에 있는 원소 갯수를 반환한다.
4. 반복문이 끝났을 때도 반환이 되지 않으면 0을 반환한다. 이 때는 모든 input이 0인 경우이다.(나도 구글링을 통해서 해당 테스트케이스를 참고해서 코드를 추가했다.)

내 코드 - 파이썬

def solution(citations):
    citations.sort()
    for idx in range(len(citations)):
        if citations[idx] >= len(citations) - idx: 
            return (len(citations) - idx)
        
    # 모든 input이 0일 때    
    return 0

문제 설명

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.
0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.

제한 사항

  • numbers의 길이는 1 이상 100,000 이하입니다.
  • numbers의 원소는 0 이상 1,000 이하입니다.
  • 정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.

입출력 예

numbers return
[6, 10, 2] 6210
[3, 30, 34, 5, 9] 9534330

 


내 문제풀이

1. numbers가 모두 0인 경우 예외처리로 먼저 return '0'을 해준다.
2. numbers를 string 타입 원소를 가진 리스트로 변환한다.
3. numbers의 원소는 모두 1000 이하의 값이기 때문에 3자리 수를 맞춰 값들을 내림차순 정렬한다.
4. numbers 값들을 하나의 string 값으로 합친다.

내 코드 - 파이썬

def solution(numbers):
    answer = ''
    
    if sum(numbers)==0:
        return '0'
    numbers = list(map(str, numbers))
    numbers.sort(key=lambda x: x*3, reverse=True)
    
    return ''.join(numbers)

+ Recent posts