[이코테] 그리디 실전문제/기출문제 풀이

soyyeong·2023년 1월 20일
0

코테

목록 보기
1/6

1. 거스름돈

카운터에 거스름돈으로 사용할 500원, 100원, 50원, 10원 짜리 동전이 무한히 존재할 때 손님에게 거슬러줘야 할 돈이 N원이다. 이떄 거슬러 줘야 할 동전의 최소 개수를 구하라
(거슬러 줘야 할 돈 N은 항상 10의 배수다)

풀이

N = int(input())

coins = [500, 100, 50, 10]
count = 0 # 동전의 개수

for coin in coins:
  count = count + N//coin
  N %= coin

print(count)

2. 큰 수의 법칙

주어진 수를 M번 더해 가장 큰 수를 만들어라. 단, 배열의 특정한 인덱스(번호)에 해당하는 수가 연속해서 K번을 초과해서 더해질 수 없다. 배열의 크기 N, 숫자가 더해지는 횟수 M, 그리고 K가 입력값임.

예시)
3,4,3,4,3 으로 이루어진 배열이 있고 M이 7이고, K가 2라 할 때 두 번째 원소 4와, 네 번째 원소 4를 번갈아 두 번씩 더해 4+4+4+4+4+4+4 = 28을 만들 수 있음

풀이 1

N, M, K = map(int, input().split())
N_data = list(map(int, input().split()))

N_data.sort() # N개의 수 오름차순 정렬

first = N_data[-1]
secon = N_data[-2]

# k번째까지 첫번째로 큰 수 더하고, k+1 번째는 두 번째로 큰 수 더하기 반복
max_sum = 0
count = 0
for i in range(M):
  if count%(K+1) == 0:
    max_sum += secon
  else:
    max_sum += first
  count += 1

print(max_sum)

풀이 2

# (6,6,6,5) + (6,6,6,5) + (6) 이런식으로 볼 수도 있음
N, M, K = map(int, input().split())
N_data = sorted(list(map(int, input().split())))

first_cnt = (M//(K+1))*K + M%(K+1)
secon_cnt = M//(K+1)
sum = N_data[-1]*first_cnt + N_data[-2]*secon_cnt

print(sum)

3. 숫자 카드 게임

숫자 카드가 N(행) x M(열) 형태로 놓여있다. 선택한 행 중에서 가장 작은 숫자를 고를때 그 숫자카드를 가장 크게 만드려고 한다.

풀이

N, M = map(int, input().split())
result = 0

for i in range(N):
  data = list(map(int, input().split()))
  min_value = min(data)
  result = max(result, min_value)

print(result)

4. 1이 될 때까지

어떤 수 N이 1이 될 때까지 아래 두 과정 중 하나를 선택하여 시도하려고 한다. 단, 두 번째 연산을 N이 K로 나누어떨어질 때만 선택할 수 있다.
1. N에서 1을 뺀다.
2. N을 K로 나눈다.
이때 1번 혹은 2번 과정을 수행해야 하는 최소 횟수를 구하라.

예시)
N이 17, K가 4라고 할 때, 1번 과정으로 한 번+2번 과정으로 두 번 수행하면 N은 1이 됨. 이는 N을 1로 만드는 최소 횟수임.

풀이

N, K = map(int, input().split())

result = 0

while True:
  if N%K == 0:
    result += 1
    N = N//K
  elif N%K != 0:
    result += 1
    N -= 1

  if N == 1:
    print(result)
    break

5. 모험가 길드

모험가 N명이 있고, 공포도 X가 있을 때, 공포도가 X인 모험가는 반드시 X명 이상으로 구성한 모험가 그룹에 참여해야 한다. 모든 모험가가 떠나지 않아도 될 때 여행을 떠날 수 있는 그룹 수의 최대값을 구하라.

예시
N = 5이고 공포도가 2 3 1 2 2 일때 그룹 1에 1,2,3인 모험가를 한 명씩 넣고, 그룹 2에 공포도가 2인 두명을 넣으면 총 2그룹을 만들 수 있음.

풀이

N = input()
N_data = sorted(list(map(int, input().split())))

ans, cnt = 0, 0
for i in N_data:
  cnt += 1
  if cnt >= i:
    ans += 1
    cnt = 0

print(ans)

6. 곱하기 혹은 더하기

0부터 9까지 숫자로 이루어진 문자열 S가 주어졌을 떄, 왼쪽부터 오른쪽으로 'X' 또는 '+' 연산자를 넣어 만들어질 수 있는 가장 큰 수를 구하라. 연산은 왼쪽부터 순서대로 이루어진다고 가정한다.

풀이

# 어짜피 0은 더해져야 하니까 0 만 빼서 다 곱하면 됨
S = list(map(int, list(input())))

multi = [S[i] for i in range(len(S)) if i != 0]

ans = 1
for n in multi:
  ans *= n

print(ans)

7. 문자열 뒤집기

문자열 S에 있는 모든 숫자를 같게 만들려고 한다.
S는 0과 1로만 이루어져 있으며 연속된 하나 이상의 숫자를 잡고 모두 뒤집을 수 있을 때 최소 횟수는?

예시
S = 0001100일때 11-> 00으로 바꿔 최소 1번을 행동해야 함.

풀이

#숫자가 바뀔 때마다 그 횟수를 세고 1을 빼주면 됨
S = input()
ans = 0
for i in range(1, len(S)):
  if S[i] != S[i-1]:
    ans += 1
  else:
    pass

print(ans-1)

8. 만들 수 없는 금액

N개의 동전을 가지고 있을 때 이걸로 만들 수 없는 양의 정수 금액 중 최솟값을 구하라.

예시)
N = 5이고 각 동전이 3, 2, 1, 1, 9원짜리 동전이라 가정하면 만들 수 없는 양의 정수 금액 중 최솟값은 8원이다.
입력)
첫 줄은 동전의 개수를 나태는 양의 정수 N, 둘째 줄은 각 화폐 단위를 나타내는 N개의 자연수

풀이

N = int(input())
N_data = sorted(list(map(int, input().split())))

ans = 1
for i in N_data:
  # 만들 수 없는 금액을 찾았을 때 반복 종료
  if ans < i:
    break
  ans += i

print(ans)

9. 볼링공 고르기

A,B 두 사람이 볼링을 치고 있다. 두 사람은 서로 무게가 다른 볼링공을 고르려 한다. 볼링공은 총 N개가 있으며 각 공마다 무게가 적혀있고, 공의 번호는 1번부터 순서대로 부여된다.
같은 무게의 공이 여러 개 있을 수 있지만 서로 다른 공으로 간주한다. 볼링공의 무게는 1부터 M까지의 자연수 형태로 존재한다.

예시)
볼링공의 개수 N=5, 공의 최대 무게 M=3 일 때,
공의 무게가 1 3 2 3 2 로 주어지면 출력은 8

풀이

처음에 여사건 써서 전체 경우의 수에서 A,B가 같은 무게의 공을 갖게 되는 경우의 수 빼면 되겠다 해서 위의 경우에 5C22C22C2=8_5C_2 - _2C_2-_2C_2 = 8 이렇게 풀려고 했는데 그냥 반복문으로 간단하게 가능했다.

N, M = map(int, input().split())
N_data = sorted(list(map(int, input().split())))

from itertools import combinations
ans = 0
for a, b in combinations(N_data, 2):
  if a == b:
    continue
  ans += 1
print(ans)

10. 무지의 먹방 라이브

프로그래머스_무지의 먹방 라이브

0개의 댓글