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