문제설명 (링크 참조)

프로그래머스 양궁 대회 문제

라이언이 어피치를 이기는 경우 중 낮은 점수를 더 많이 맞힌 경우를 리턴, 리턴 값은 10점 화살의 개수 부터 0점까지 리스트 형식으로 반환 한다.
ex [1,2,3,0,0,0,0,0,0,0,1]
단 어떠한 경우에도 못이기면 -1 리턴.

풀이

결국은 라이언이 어피치를 이기는 경우를 체크해주면 된다.

코드는 이런방법으로 작성했다.

  1. 우선 0~10의 화살을 쏠 수 있는 경우의 수를 조합을 이용해 뽑았다. (여기서 같은 점수를 여러번 맞힐 수 있으므로 중복이 가능하게 뽑아야 했다. 그래서 그냥 combinations가 아닌 combinations_with_replacement 사용.)
  2. 나온 경우의 수와 어피치의 과녁을 비교해서 라이언이 더 많이 맞힌 수는 라이언의 점수로, 어피치가 더많이 맞혔거나 같으면 어피치 점수로, 둘다 0이면 점수를 세지 않았다.

-> 여기서 여러발을 맞혀도 누적 점수가 아닌 과녁의 점수만 +해줘야한다.

  1. 점수를 체크한 뒤 라이언이 어피치보다 더 많은 점수를 획득했을 때, 가장 큰 차이로 이기는 경우를 찾아야 한다. 그래서 count 변수로 점수의 차이를 저장해놓고 현재 결과 점수가 count보다 클경우 c배열과 count 업데이트.
  2. 그렇게 찾은 조합을 점수로 변환한 후 answer에 넣어서 return

코드

from itertools import combinations_with_replacement
def solution(n, info):
    arr=[0,1,2,3,4,5,6,7,8,9,10]
    b=list(combinations_with_replacement(arr,n))
    # 가능한 모든 경우의 수를 중복 조합으로 구함.
    c=[] #결과 저장할 배열 선언
    count=0
    for i in range(len(b)):
        l=0
        a=0
        for j in range(11):
            if(info[j]<b[i].count(10-j)):
                l+=10-j
            elif(info[j]>=b[i].count(10-j) and info[j]!=0):
                a+=10-j
                #둘다 0이면 그냥 넘어간다.
        if(l<a):
            continue
        elif(l>a):
            #라이언이 이기는 경우 중에서도 최대 점수차이가 나올때만 업데이트.
            if(count<l-a):
                count=l-a
                c=b[i]

        else:
            continue
    answer=[0,0,0,0,0,0,0,0,0,0,0]
    #결과 배열이 비어있으면 -1 리턴.
    if(len(c)==0):
        return [-1]
    #결과 배열의 값을 answer배열의 인덱스로 사용해서 답 작성.
    for i in range(len(c)):
        answer[10-c[i]]+=1
    return answer

특이사항

  • 둘다 0이면 점수를 세지 않는 조건을 생각하지 않아서 몇번 틀림
  • 그리고 조건중에 “같은 점수일경우 적은 수의 과녁을 더 많이 맞힌 경우를 우선한다”라는 조건이 있었는데 딱히 신경안써도 통과해서 왜 그럴지 고민함
    → 고민한 결과 조합을 함수로 구했을 경우 배열의 앞쪽부분을 순서대로 먼저 조합으로 구함. 즉 arr이 0,1,2..순서대로 시작했기 때문에 0,1,2..순서대로 많은 조합부터 구한 것!
    그렇기 때문에 코드에서는 점수가 똑같을 경우를 생각 안하고 클때만 바꿨지만, 결국 점수가 같을 경우를 체크해도 앞에 나온게 무조건 우선일 수 밖에 없다. (상대적으로 낮은 번호의 수가 더 많기 때문에)

+ Recent posts