[ 프로그래머스 / PYTHON ] 양궁대회

yujeongkwon·2022년 6월 29일
0

프로그래머스 / PYTHON

목록 보기
35/77
post-custom-banner

문제 설명

양궁대회

  1. 어피치가 화살 n발을 다 쏜 후에 라이언이 화살 n발을 쏩니다.
  2. 점수를 계산합니다.
    2-1 과녁판은 아래 사진처럼 생겼으며 가장 작은 원의 과녁 점수는 10점이고 가장 큰 원의 바깥쪽은 과녁 점수가 0점입니다.

    2-2 만약, k(k는 1~10사이의 자연수)점을 어피치가 a발을 맞혔고 라이언이 b발을 맞혔을 경우 더 많은 화살을 k점에 맞힌 선수가 k 점을 가져갑니다. 단, a = b일 경우는 어피치가 k점을 가져갑니다. k점을 여러 발 맞혀도 k점 보다 많은 점수를 가져가는 게 아니고 k점만 가져가는 것을 유의하세요. 또한 a = b = 0 인 경우, 즉, 라이언과 어피치 모두 k점에 단 하나의 화살도 맞히지 못한 경우는 어느 누구도 k점을 가져가지 않습니다.
    2-3. 모든 과녁 점수에 대하여 각 선수의 최종 점수를 계산합니다.
  3. 최종 점수가 더 높은 선수를 우승자로 결정합니다. 단, 최종 점수가 같을 경우 어피치를 우승자로 결정합니다.

화살의 개수를 담은 자연수 n, 어피치가 맞힌 과녁 점수의 개수를 10점부터 0점까지 순서대로 담은 정수 배열 info가 매개변수로 주어집니다. 이때, 라이언이 가장 큰 점수 차이로 우승하기 위해 n발의 화살을 어떤 과녁 점수에 맞혀야 하는지를 10점부터 0점까지 순서대로 정수 배열에 담아 return 하도록 solution 함수를 완성해 주세요. 만약, 라이언이 우승할 수 없는 경우(무조건 지거나 비기는 경우)는 [-1]을 return 해주세요.

[입출력 예]

ninforesult
5[2,1,1,1,0,0,0,0,0,0,0][0,2,2,0,1,0,0,0,0,0,0]
1[1,0,0,0,0,0,0,0,0,0,0][-1]
9[0,0,1,2,0,1,1,1,1,1,1][1,1,2,0,1,2,2,0,0,0,0]
10[0,0,0,0,0,0,0,0,3,4,3][1,1,1,1,1,1,1,1,0,0,2]

나의 생각

화살을 쏠려면 3가지의 경우의 수가 있다.
1. 어피치가 쏜 것을 피하고 화살을 아낀 후 다른 점수를 맞춘다.
2. 어피치가 쏜 것을 뺐는다. 어피치 점수 -= 해당점수, 라이언 점수 += 해당점수
3. 어피치가 쏘지 않은 것을 쏜다. 라이언 점수 += 해당 점수

이 점에 주의하여 라이언의 점수를 모두 더한 뒤 (라이언 점수 - 어피치 점수)가 가장 큰 화살의 배열을 return 하면 된다.

어피치와 라이언의 점수에 해당 점수를 더하거나 뺀 값을 방문하기에 엣지가 3(위에 언급한 3가지의 경우의 수)인 트리 구조를 볼 수 있다.

따라서 나는 재귀를 활용한 DFS를 활용하여 문제를 해결했다.

여기서 내가 간과한 점이 있는데,

❗ "라이언이 가장 큰 점수 차이로 우승할 수 있는 방법이 여러 가지 일 경우, 가장 낮은 점수를 더 많이 맞힌 경우를 return 해주세요."

위 조건을 확인하지 못해 케이스 8, 18의 경우만 틀렸고,

❗ 라이언이 이길수 없는 경우, 어피치와 점수가 동일한 경우 answer == [0,0,0,0,0,0,0,0,0,0,0], max_ = 0일 경우를 간과했다.

처음 문제를 해결하니 위 문제로인해 케이스 23이 통과가 되지 않았다.

🔎한번 더 푼 후기

인간은 같은 실수를 반복하지 ㅎ9ㅎ.. 이거 예전에 엄청 낑낑대다가 한번 머리 잘돌아갈때 생각보다 빨리 풀었던 코드인데 오히려 그때보다 훠어어ㅓ럴신 더 오래걸림 저때는 경우의수를 3가지 한번에 생각했는데 이번에는 3번 경우의 수를 2번에 합쳐도 되는줄알았다 ^9^.. 어피치 점수가 이유없이 - 되는데 ㅎ.ㅎ....
물론 전에 못봤던 8,18,23의 예외케이스를 확인하지 못했따. 예외가 있다는 걸 찾아아 코테에서 맞출 수 있을텐데 난 글렀어 사람이 발전이없고 후퇴만있다ㅠ

코드

함수 인자로 리스트를 넘길 때, 깊은 복사 해결 import copy
[TIL / Python] 얕은복사, 깊은 복사 ( 리스트를 함수 인자로 받을 때)
2022.06.30 코드

import copy            
def solution(n, info):
    answer = [0,0,0,0,0,0,0,0,0,0,0]
    count, a_score, l_score= 0,0,0
    max_  = 0 
    
    for i in range(11):
        if info[i]: a_score += 10-i
    
    def dfs(a_score,l_score, idx,li):
        temp = copy.deepcopy(li)
        if idx >= 11 or sum(temp) >= n:
            nonlocal max_
            nonlocal answer
            if max_ < l_score - a_score:
                max_ = l_score - a_score
                answer = temp
            elif max_ == l_score - a_score:
                a,b = 0,0
                for i in range(11):
                    if answer[i]:   a+=i
                    if temp[i]: b+=i
                if b>=a: answer = temp
            return
        else:
            #피하고 다른 것
            dfs(a_score,l_score,idx+1,temp)
            # 어피치 것 뻇기
            if sum(temp) + info[idx] +1 <= n and info[idx] != 0:
                a_score -= 10- idx
                l_score += 10 - idx
                temp[idx] = info[idx] + 1
                dfs(a_score,l_score,idx+1,temp)
            elif info[idx] == 0:    #어피치가 안 쏜것
                l_score += 10 - idx
                temp[idx] = 1
                dfs(a_score,l_score,idx+1,temp)
    
    dfs(a_score,l_score,0,answer)
    if answer == [0,0,0,0,0,0,0,0,0,0,0] or max_==0:   return [-1]
    else: 
        if sum(answer) < n:   answer[-1] = n - sum(answer)
        return answer

2022.08.02 코드

import copy

def solution(n, info):
    answer = [0 for i in range(11)]
    max_,apeachScore  = 0,0
    
    for i in range(len(info)):
        if info[i] != 0:  apeachScore += 10-i
    
    def dfs(apeachScore,lionScore,arrow,count,li):
        temp = copy.deepcopy(li)
        if count>=11 or arrow==0:  
            nonlocal max_
            nonlocal answer
            if arrow > 0:   temp[-1]=arrow
            if max_ < lionScore - apeachScore : 
                if arrow>0: answer[-1] = arrow
                max_ = lionScore - apeachScore
                answer = temp
            elif max_ == lionScore - apeachScore:
                a,b = 0,0
                for i in range(11):
                    if answer[i]:   a+=i
                    if temp[i]: b+=i
                if b>=a: answer = temp
            return
        else:
            # 넘기기
            dfs(apeachScore,lionScore,arrow,count+1,temp)
            #어피치보다 많이 쏘기
            if arrow-info[count]-1 >=0 and info[count] != 0:
                temp[count] = info[count] + 1
                dfs(apeachScore-(10-count),lionScore+(10-count),arrow-info[count]-1,count+1,temp)
            elif info[count] == 0:    #어피치가 안 쏜것
                lionScore += 10 - count
                temp[count] = 1
                dfs(apeachScore,lionScore,arrow-info[count]-1,count+1,temp)
    dfs(apeachScore,0,n,0,answer)
    return answer if answer != [0,0,0,0,0,0,0,0,0,0,0] and  max_ !=0  else [-1]
profile
인생 살자.
post-custom-banner

0개의 댓글