2 분 소요

문제 링크

내 풀이

# k(k는 1~10사이의 자연수)점 더 많은 화살을 k점에 맞힌 선수가 k 점을 가져갑니다(여러발 맞춰도 k점만 가져감)
# 단 같을 경우 어피치가 점수가져감
# k점 보다 많은 점수를 가져가는 게 아니고 k점만 가져가는 것을 유의
# a = b = 0 인 경우 아무도 K점 안가져감
# 최종 점수 큰사람이 우승자, 같을 경우 어피치가 우승자
# 가장 큰 점수 차이로 이기기 위해서 n발의 화살을 어떤과녁 점수에 맞혀야 하는지 구하기
# 10점부터 0점까지 순서대로 정수 배열에 담아 return (몇발씩 맞춰야하는지)
# 라이언이 우승할 수 없는 경우(지거나 비기는 경우) [-1] 리턴
# info => 어피치가 맞힌 과념점수 개수 리스트

# (제한 사항)
# 가장 큰 점수 차이로 우승할 수 있는 방법이 여러 가지 일 경우, 가장 낮은 점수를 더 많이 맞힌 경우를 return
# 가장 낮은 점수를 맞힌 개수가 같을 경우 계속해서 그다음으로 낮은 점수를 더 많이 맞힌 경우를 return

# 어피치를 이길때마다 점수차이와 그 당시 화살점수 리스트를 저장
# 점수차이가 클때마다 갱신
# 점수차이 같을경우 리스트에 추가
# 최종결과 리스트 길이가 1보다 클 때 가장 작은 점수 개수 기준으로 최종 리스트 결정
# 동시에 pop해오다가 가장 큰 값을 가진 리스트 return
# info의 수보다 최대한 한개 큰수를 넣고 점수계산 작게 넣을바에 아예안넣음 

def calc_score(info, ryan):
    appeach_score = 0
    ryan_score = 0  
    for i in range(len(info)):
        if info[i] >= ryan[i] and info[i] != 0:
            appeach_score += 10 - i
        else:
            ryan_score += 10 - i
    return [appeach_score, ryan_score]
        

def make_ryan(score_max, info, ryan, bow, i, n):
    a_score, r_score = calc_score(info, ryan)
    if bow == n:
        # score_list.append(ryan) # 역대 최대일때 append 해주기
        return r_score
    for _ in range(n):
        if bow + info[i] + 1 <= n:
            bow += info[i] + 1
            score_max = max(score_max, make_ryan(info, ryan, bow, i + 1))
            bow -= ryan[i]
            ryan[i] = 0
    
def solution(n, info):
    ryan = [0] * 11  

정답 풀이

from itertools import combinations_with_replacement
from collections import Counter

def solution(n, info):
  maxdiff, max_comb = 0, {}

  # ➊ 주어진 조합에서 각각의 점수 계산
  def calculate_score(combi):
    score1, score2 = 0, 0
    for i in range(1, 11):
      if info[10 - i] < combi.count(i):
        score1 += i
      elif info[10 - i] > 0:
        score2 += i
    return score1, score2

  # ➋ 최대 차이와 조합 저장
  def calculate_diff(diff, cnt):
    nonlocal maxdiff, max_comb
    if diff > maxdiff:
      max_comb = cnt
      maxdiff = diff

  # ➌ 가능한 라이언의 과녁점수 조합의 모든 경우에 대해서 체크
  for combi in combinations_with_replacement(range(11), n):
    cnt = Counter(combi)
    score1, score2 = calculate_score(combi)
    diff = score1 - score2
    calculate_diff(diff, cnt)

  # ➍ 최대 차이가 0 이상인 경우, 조합 반환
  if maxdiff > 0:
    answer = [0] * 11
    for n in max_comb:
      answer[10 - n] = max_comb[n]
    return answer
  else:  # ➎ 최대 차이가 0인 경우, -1 반환
    return [-1]

풀이 해석

  • combinations_with_replacement를 통해 중복포함 모든조합을 표현하였다.
  • ex. combinations_with_replacemnet(range(11), n)

배울점

  • from itertools import combinations_with_replacement
  • nonlocal 변수

댓글남기기