매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같이 특별한 방법으로 섞어 새로운 음식을 만듭니다.
섞은 음식의 스코빌 지수 = 가장 맵지 않은 음식의 스코빌 지수 + (두 번째로 맵지 않은 음식의 스코빌 지수 * 2)
Leo는 모든 음식의 스코빌 지수가 K 이상이 될 때까지 반복하여 섞습니다. Leo가 가진 음식의 스코빌 지수를 담은 배열 scoville과 원하는 스코빌 지수 K가 주어질 때, 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 섞어야 하는 최소 횟수를 return 하도록 solution 함수를 작성해주세요.
제한 사항
scoville의 길이는 2 이상 1,000,000 이하입니다.
K는 0 이상 1,000,000,000 이하입니다.
scoville의 원소는 각각 0 이상 1,000,000 이하입니다.
모든 음식의 스코빌 지수를 K 이상으로 만들 수 없는 경우에는 -1을 return 합니다.
입출력 예
scovilleKreturn
[1, 2, 3, 9, 10, 12]
7
2
입출력 예 설명
스코빌 지수가 1인 음식과 2인 음식을 섞으면 음식의 스코빌 지수가 아래와 같이 됩니다. 새로운 음식의 스코빌 지수 = 1 + (2 * 2) = 5 가진 음식의 스코빌 지수 = [5, 3, 9, 10, 12]
스코빌 지수가 3인 음식과 5인 음식을 섞으면 음식의 스코빌 지수가 아래와 같이 됩니다. 새로운 음식의 스코빌 지수 = 3 + (5 * 2) = 13 가진 음식의 스코빌 지수 = [13, 9, 10, 12]
모든 음식의 스코빌 지수가 7 이상이 되었고 이때 섞은 횟수는 2회입니다
import heapq
def solution(scoville, K):
answer = 0
heapq.heapify(scoville)
if scoville[0] >= K:
return 0
while len(scoville)>=2:
if scoville[0] >= K:
break
else:
new = heapq.heappop(scoville) + 2* heapq.heappop(scoville)
heapq.heappush(scoville, new)
answer += 1
if scoville[0] < K:
return -1
else:return answer
def solution(phone_book):
answer = True
phone_book = sorted(phone_book, key=len)
for i in range(len(phone_book)-1):
for j in range(i+1, len(phone_book)):
if phone_book[i]==phone_book[j][:len(phone_book[i])]:
return False
return answer
startswith() 함수를 이용한 풀이
def solution(phoneBook):
phoneBook = sorted(phoneBook)
for p1, p2 in zip(phoneBook, phoneBook[1:]):
if p2.startswith(p1):
return False
return True
트럭 여러 대가 강을 가로지르는 일 차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 트럭은 1초에 1만큼 움직이며, 다리 길이는 bridge_length이고 다리는 무게 weight까지 견딥니다. ※ 트럭이 다리에 완전히 오르지 않은 경우, 이 트럭의 무게는 고려하지 않습니다.
예를 들어, 길이가 2이고 10kg 무게를 견디는 다리가 있습니다. 무게가 [7, 4, 5, 6]kg인 트럭이 순서대로 최단 시간 안에 다리를 건너려면 다음과 같이 건너야 합니다.
경과 시간다리를 지난 트럭다리를 건너는 트럭대기 트럭
0
[]
[]
[7,4,5,6]
1~2
[]
[7]
[4,5,6]
3
[7]
[4]
[5,6]
4
[7]
[4,5]
[6]
5
[7,4]
[5]
[6]
6~7
[7,4,5]
[6]
[]
8
[7,4,5,6]
[]
[]
따라서, 모든 트럭이 다리를 지나려면 최소 8초가 걸립니다.
solution 함수의 매개변수로 다리 길이 bridge_length, 다리가 견딜 수 있는 무게 weight, 트럭별 무게 truck_weights가 주어집니다. 이때 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 return 하도록 solution 함수를 완성하세요.
from collections import deque
import math
def solution(progresses, speeds):
answer = []
q = []
for i in range(len(progresses)):
q.append(math.ceil((100-progresses[i]) / speeds[i]))
q = deque(q)
while q:
cnt = 1
x = q.popleft()
temp = 0
for i in q:
if i<=x:
temp += 1
else: break
cnt += temp
for _ in range(temp):
q.popleft()
answer.append(cnt)
return answer
풀이2: 덱 없이 리스트에서 수를 전처리 시켜두고 풀기
import math
def solution(progresses, speeds):
answer = []
cnt = 1
q = []
for i in range(len(progresses)):
q.append(math.ceil((100-progresses[i]) / speeds[i]))
for i in range(1, len(q)):
if q[i-1] >= q[i]:
q[i] = q[i-1]
for i in range(1, len(q)):
if q[i-1]>=q[i]:
cnt += 1
else:
answer.append(cnt)
cnt = 1
answer.append(cnt)
return answer
solution.c 1 #include <stdio.h> 2 #include <stdbool.h> 3 #include <stdlib.h> 4 5 // prices_len은 배열 prices의 길이입니다. 6 int* solution ( int prices [], size_t prices_len ) { 7 // return 값은 malloc 등 동적 할당을 사용해주세요. 할당 길이는 상황에 맞게 변경해주세요. 8 int* answer = ( int* ) malloc ( 1 ); 9 return answer ; 10 } 실행 결과 ...
programmers.co.kr
문제 설명
초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 떨어지지 않은 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요.
제한사항
prices의 각 가격은 1 이상 10,000 이하인 자연수입니다.
prices의 길이는 2 이상 100,000 이하입니다.
입출력 예
prices
return
[1, 2, 3, 2, 3]
[4, 3, 1, 1, 0]
비교적 빠른 시간 안에 아이디어를 잡고 구현까지 성공했다.
큐/스택 카테고리에 들어가있던 문제이지만 큐, 스택과는 관계없이 대소관계를 비교하며
이중 반복문으로 풀 수 있었다.
def solution(prices):
answer = []
for i in range(len(prices)):
cnt = 0
for j in range(i+1, len(prices)):
cnt +=1
if prices[i] > prices[j] :
break
answer.append(cnt)
return answer
큐와 스택을 이용해서 푸는 풀이는 없나하고 다른 사람의 문제 풀이를 참조해봤지만
돌아가는 구조 자체는 위와 크게 다르지 않았다.
prices를 deque() 를 이용해서 덱으로 만든 다음 popleft 를 이용해 맨 왼쪽 값을 빼내는 것 정도.
예를 들어 선행 스킬 순서가 스파크 → 라이트닝 볼트 → 썬더일때, 썬더를 배우려면 먼저 라이트닝 볼트를 배워야 하고, 라이트닝 볼트를 배우려면 먼저 스파크를 배워야 합니다.
위 순서에 없는 다른 스킬(힐링 등)은 순서에 상관없이 배울 수 있습니다. 따라서 스파크 → 힐링 → 라이트닝 볼트 → 썬더와 같은 스킬트리는 가능하지만, 썬더 → 스파크나 라이트닝 볼트 → 스파크 → 힐링 → 썬더와 같은 스킬트리는 불가능합니다.
선행 스킬 순서 skill과 유저들이 만든 스킬트리1를 담은 배열 skill_trees가 매개변수로 주어질 때, 가능한 스킬트리 개수를 return 하는 solution 함수를 작성해주세요.
제한 조건
스킬은 알파벳 대문자로 표기하며, 모든 문자열은 알파벳 대문자로만 이루어져 있습니다.
스킬 순서와 스킬트리는 문자열로 표기합니다.
예를 들어, C → B → D 라면 CBD로 표기합니다
선행 스킬 순서 skill의 길이는 1 이상 26 이하이며, 스킬은 중복해 주어지지 않습니다.
skill_trees는 길이 1 이상 20 이하인 배열입니다.
skill_trees의 원소는 스킬을 나타내는 문자열입니다.
skill_trees의 원소는 길이가 2 이상 26 이하인 문자열이며, 스킬이 중복해 주어지지 않습니다.
입출력 예
skill
skill_trees
return
"CBD"
["BACDE", "CBADF", "AECB", "BDA"]
2
정해진 스킬트리의 순서를 인식하고, 그 스킬트리의 순서에 맞게 스킬을 찍고 있는지를 확인하기 위해
skill문자열을 덱으로 바꿔서 popleft() 를 쓸 수 있게 했다.
저렇게 풀다가 막힌 부분이 CBD의 스킬트리에서 D까지 스킬을 다 찍었을 때 q에 더 이상 요소가 남아있지 않아 popleft()실행 시 IndexError가 발생한다는 점이었는데,
try except문을 사용함과 동시에 스킬트리 순서를 지킨 개수를 answer에 하나씩 더하는 것보다
시작과 동시에 주어진 skill_trees의 개수를 answer에 넣어두고 스킬트리 순서를 지키지 않은 개수를 answer에서 하나씩 빼는 방법으로 접근했다. 코드모양이 조금 길어진 것 같지만 다른 접근방법으로 해결할 수 있어서 기뻤다.
from collections import deque
def solution(skill, skill_trees):
answer = len(skill_trees)
for tree in skill_trees:
q = deque(skill)
s = q.popleft()
for v in tree:
if v in q:
answer -= 1
break
elif s == v:
try:
s = q.popleft()
except IndexError:
break
return answer
def solution(priorities, location):
answer = 0
priorities_copy = [0 for _ in range(len(priorities))]
priorities_copy[location] = 1
while True:
if priorities[0] == max(priorities):
answer += 1
if not priorities_copy[0]:
del priorities[0]
del priorities_copy[0]
else:break
else:
priorities.append(priorities[0])
priorities_copy.append(priorities_copy[0])
del priorities_copy[0]
del priorities[0]
return answer
다른 사람의 풀이 보기를 해봤더니
python 내장함수인 any함수를 이용해서 푼 신기한 풀이가 있길래 공부가 되었다.
any함수를 이용한 풀이코드
def solution(priorities, location):
queue = [(i,p) for i,p in enumerate(priorities)]
answer = 0
while True:
cur = queue.pop(0)
if any(cur[1] < q[1] for q in queue):
queue.append(cur)
else:
answer += 1
if cur[0] == location:
return answer
python any 함수는 반복 가능한(iterable) 자료형 x를 입력 인수로 받으며 이 x의 요소 중 하나라도 참이 있으면 True를 돌려주고, x가 모두 거짓일 때에만 False를 돌려주는 함수이다. 파이썬의 내장 함수이다.