문제설명 (링크 참조)
라이언이 어피치를 이기는 경우 중 낮은 점수를 더 많이 맞힌 경우를 리턴, 리턴 값은 10점 화살의 개수 부터 0점까지 리스트 형식으로 반환 한다.
ex [1,2,3,0,0,0,0,0,0,0,1]
단 어떠한 경우에도 못이기면 -1 리턴.
풀이
결국은 라이언이 어피치를 이기는 경우를 체크해주면 된다.
코드는 이런방법으로 작성했다.
- 우선 0~10의 화살을 쏠 수 있는 경우의 수를 조합을 이용해 뽑았다. (여기서 같은 점수를 여러번 맞힐 수 있으므로 중복이 가능하게 뽑아야 했다. 그래서 그냥 combinations가 아닌 combinations_with_replacement 사용.)
- 나온 경우의 수와 어피치의 과녁을 비교해서 라이언이 더 많이 맞힌 수는 라이언의 점수로, 어피치가 더많이 맞혔거나 같으면 어피치 점수로, 둘다 0이면 점수를 세지 않았다.
-> 여기서 여러발을 맞혀도 누적 점수가 아닌 과녁의 점수만 +해줘야한다.
- 점수를 체크한 뒤 라이언이 어피치보다 더 많은 점수를 획득했을 때, 가장 큰 차이로 이기는 경우를 찾아야 한다. 그래서 count 변수로 점수의 차이를 저장해놓고 현재 결과 점수가 count보다 클경우 c배열과 count 업데이트.
- 그렇게 찾은 조합을 점수로 변환한 후 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..순서대로 많은 조합부터 구한 것!
그렇기 때문에 코드에서는 점수가 똑같을 경우를 생각 안하고 클때만 바꿨지만, 결국 점수가 같을 경우를 체크해도 앞에 나온게 무조건 우선일 수 밖에 없다. (상대적으로 낮은 번호의 수가 더 많기 때문에)
'알고리즘' 카테고리의 다른 글
[백준] 20006 랭킬전 대기열 python (0) | 2024.01.19 |
---|---|
[프로그래머스] 방문 길이 python (0) | 2024.01.18 |
[프로그래머스] 호텔 대실 python (0) | 2024.01.17 |
[프로그래머스] 문자열 압축 python (1) | 2023.10.02 |
[프로그래머스] 튜플 Python (0) | 2023.10.02 |