7106번 Wonderful Fours

문제


img01

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)

채점


img02

반성


머리아파서 뇌비우고 하다가 그래도 더 잘할 수 있지 않나? 하는 마음에 탈출코드 추가해서 시간을 줄였다.
이제 5중 나생문을 해체하려고 보는 순간 다시 머리가 아파서 관뒀다.
휴식이 필요한 하루다…

얼마나 머리아프냐면 생각없이 파이썬 코드를 C++코드로 제출해서 컴파일 오류남

코드 확인


Link to GitHub

Updated: