7106번 Wonderful Fours
문제
번역
브론즈 문제 하나, 텍스트 제출 문제 하나 거르고 나온 실버 문제.
내 그지같은 파이썬 실력에 알맞은 난이도다.
찬찬히 해석해보면…
십진수 숫자 5개를 K5라 부른다.
모두 사용하되 0으로 시작하지 않는 숫자를 만들면 그 숫자는 ‘적절히’ 만들어진 것이다.
그리고 아래 내용이 모두 참일 경우 완다풀 포가 된다.
- 4개의 5자리 자연수가 모두 적절하게 만들어짐
- 4개의 5자리 자연수는 모두 다른 숫자
- s1 + s2 + s3 = s4
여기서 주어진 K5로 몇 개의 서로 다른 완다풀 포를 만들 수 있는지 계산하시오.
설계
뭐 방법이 있나?
숫자 크기도 작고 그냥 세개 뽑아서 합해서 찾아보면 되겠다.
중복 제거에만 신경쓰면 될 듯
구현
중복 제거를 고민해봤는데
처음부터 ‘적절한’ 숫자를 만들며 중복되는걸 날려버리면 끝이다.
1. 입력받아 ‘적절한’ 숫자 만들기
더 똑똑하게 할 수 있지만
겨우 숫자 다섯개로 하는거니 5중 나생문을 쌓았다.
중복 거르고 정렬.
K5 = input().split()
r = 0
# 적절한 숫자 생성(중복제외)
all_num = set()
# 몇개 안되고 귀찮으니 5중반복문
for i in range(5):
for j in range(5):
if j == i:
continue
for k in range(5):
if k == i or k == j:
continue
for l in range(5):
if l == i or l == j or l == k:
continue
for m in range(5):
if m == i or m == j or m == k or m == l:
continue
num_str = K5[i] + K5[j] + K5[k] + K5[l] + K5[m]
if num_str[0] != '0':
all_num.add(int(num_str))
all_num = list(all_num)
all_num.sort()
2. 완다풀 포 구하기
미리 중복 거르고 정렬해놔서 중복체크는 할 필요 없고
리스트의 최대값보다 합이 커지면 더 탐색할 필요없이 break 한다.
length = len(all_num)
max = all_num[length-1]
# list 순회하며 s1 + s2 + s3 = s4 조건 확인
if length >= 4:
for i in range(length):
for j in range(i + 1, length):
for k in range(j + 1, length):
s1, s2, s3 = all_num[i], all_num[j], all_num[k]
s4 = s1 + s2 + s3
if s4 > max:
# 최대 숫자보다 크면 탈출
break
if s4 in all_num:
r+=1
print(r)
채점
반성
머리아파서 뇌비우고 하다가 그래도 더 잘할 수 있지 않나? 하는 마음에 탈출코드 추가해서 시간을 줄였다.
이제 5중 나생문을 해체하려고 보는 순간 다시 머리가 아파서 관뒀다.
휴식이 필요한 하루다…
얼마나 머리아프냐면 생각없이 파이썬 코드를 C++코드로 제출해서 컴파일 오류남
코드 확인