doDFS(depth + 1, plus, minus, multiply, divide - 1, result // num[depth])
''' 저번 시간 코드 참고. 코드 전문이 아니라 오류가 생긴 코드만 확인해야 하니 오류 부분만 가져왔다.'''
저번에 작성했던 코드의 문제를 발견했다. // 연산자와 int( / )의 연산의 차이를 몰라서 해결이 안 됐다.
요지는 이것이었다.
- // 연산자는 산술 연산 후 몫만 취하는 함수이다.
- 몫만 취한다는 의미는 나머지를 버린다는 의미와 동일하다.
- 그렇다면 정수 부분을 반환하는 int( / )와 같지 않은가?
결과적으로 아니다. // 연산은 정확하게 따지면 floor() 연산을 실행하고 있었다. int()는 trunc()와 동일하다.
floor()는 소수점을 '내림'을 하는 거고, trunc()는 소수점을 '버림'하는 연산이었다. 수학에서 내림 계산은 양수일 때는 0에 가까워지려는 계산을 하지만,
음수일 때는 0에서 멀어지려는 계산을 한다. 버림은 그냥 버리는 거고.
영문 명칭도 floor division이다. 이런 거 없이 교재에서 몫만 취한다고 써놓으니 이해가 안 되지...
또, 나눗셈은 정수 나눗셈으로 몫만 취한다. 음수를 양수로 나눌 때는 C++14의 기준을 따른다. 즉, 양수로 바꾼 뒤 몫을 취하고, 그 몫을 음수로 바꾼 것과 같다. 이에 따라서, 위의 식 4개의 결과를 계산해보면 아래와 같다.
어찌되었든 문제로 돌아와서 몫만 취한다는 개념으로 접근했을 때, 음수의 관점에서도 몫이 변하면 안 된다.
floor는 음수의 결괏값이 나올 때 몫이 변할 수 있으므로 안전하게 int형변환으로 소수점을 버리는 것이다.
N = int(input())
num = list(map(int, input().split()))
opCnt = list(map(int, input().split()))
maxNum = -1e9
minNum = 1e9
def doDFS(depth, plus, minus, multiply, divide, result):
global maxNum, minNum
if depth == N:
maxNum = max(result, maxNum)
minNum = min(result, minNum)
return
if plus != 0:
doDFS(depth + 1, plus - 1, minus, multiply, divide, result + num[depth])
if minus != 0:
doDFS(depth + 1, plus, minus - 1, multiply, divide, result - num[depth])
if multiply != 0:
doDFS(depth + 1, plus, minus, multiply - 1, divide, result * num[depth])
if divide != 0:
doDFS(depth + 1, plus, minus, multiply, divide - 1, int(result / num[depth]))
doDFS(1, opCnt[0], opCnt[1], opCnt[2], opCnt[3], num[0])
print(maxNum)
print(minNum)
고로 완성된 코드는 위와 같다. 교수님께 여쭤봤지만 기억이 안 나신다고 하셨다...
하지만 음수 계산을 할 때 맨 앞에 0과 1의 차이로 음수가 결정이 되니 그 부분의 매커니즘과 관련이 있지 않을까 하고 조언을 주신 게 도움이 되었다.
역시 모를 땐 질문이지.
'PS > 구현' 카테고리의 다른 글
[백준] No.1764_듣보잡 01 (0) | 2022.08.04 |
---|---|
[백준] No.14888_연산자 끼워넣기 完 (0) | 2022.03.15 |
[백준] No.14888_연산자 끼워넣기 01 (0) | 2022.03.12 |
[백준] No.9663_N-Queen 完 (0) | 2022.03.09 |
[백준] No.9663_N-Queen 01 (0) | 2022.03.09 |