#14888

zzwwoonn·2022년 5월 25일
0

Algorithm

목록 보기
33/71

입력 받을 때, 더하기 빼기 곱하기 나누기

내가 한 풀이

operInput = list(map(int, input().split()))
oper = ["+", "-", "x", "%"]
operList = []

for i in range(len(operInput)):
    for j in range(int(operInput[i])):
        operList.append(oper[i])

답지 풀이

add, sub, mul, div = map(int, input().split())

=> 입력을 받을 때 부터 애초에 숫자(개수)이고 "+" 와 같은 문자열을 바로 써줄 것이 아니므로 굳이 내가 한대로 할 필요없고 개수만 세어줘도 된다.

최대값, 최소값 정의하기

maxVal = -1e9
minVal = 1e9

현재의 최대값, 최소값과 지금까지의 배열을 두고 최대값, 최소값 갱신하기

( + 탈출 조건)

if i == n:
	maxVal = max(maxVal, arr)
	minVal = min(minVal, arr)

입력받은 수열의 제일 처음 숫자는 그대로 넣어주고 -> 무조건이니까
그 다음부터 연산자 하나, 숫자 하나 이렇게 dfs 를 타고타고 깊이 들어가보면 되고

이까진 얼추 비슷하게 접근 방향은 맞았던 것 같다.

내가 짰던 코드

N = int(input())
numList = list(map(int, input().split()))
operInput = list(map(int, input().split()))
oper = ["+", "-", "x", "%"]
operList = []

for i in range(len(operInput)):
    for j in range(int(operInput[i])):
        operList.append(oper[i])

# print(numList)
# print(operList)

cnt = 0
answer = 0
answer += numList[0]

usedOperList = []

def dfs(numidx, operidx):
    global answer
    global cnt

    if cnt == len(operList):
        return
    
    if operidx not in usedOperList:
        # 안 쓴 연산자이면, 썼던 연산자(인덱스) 기억해두고 다음 번에 왔을 때 그거 빼고 돌아 

        print("operList[", operidx, "]" , operList[operidx], "는 안쓴 연산자, ", " usedOperList = ", usedOperList)
        usedOperList.append(operidx)

    if (operList[operidx] == "+"):
        answer += numList[numidx]
    if (operList[operidx] == "-"):
        answer -= numList[numidx]
    if (operList[operidx] == "x"):
        usedOperList.append(operidx)
        answer *= numList[numidx]
    if (operList[operidx] == "%"):
        usedOperList.append(operidx)
        answer = int(answer // numList[numidx])
    
    cnt += 1

    print("cnt = ", cnt)
    print("answer = ", answer)

    # if maxVal < answer:
    #     maxVal = answer
    # if minVal > answer:
    #     minVal = answer

    dfs(numidx+1, operidx+1)
    
for i in range(len(numList)):
    # 숫자 하나당 연산자 다 돌아

    for j in range(len(operList)):
        # i 는 0, 1, 2, 3, 4 

        dfs(i+1, j)

정답 코드

N = int(input())
numList = list(map(int, input().split()))
add, sub, mul, div = map(int, input().split())

maxVal = -1e9
minVal = 1e9

def dfs(i,resultVal):
    global add, sub, mul, div, maxVal, minVal

    if i == N:
        maxVal = max(maxVal,resultVal)
        minVal = min(minVal,resultVal)
    else:
        if add > 0:
            add -= 1
            # 하기 전에 쓰고
            dfs(i+1,resultVal + numList[i])
            # 그거 진행하고
            add += 1
            # 끝나면 다시 돌려주고
        if sub > 0:
            sub -= 1
            # 하기 전에 쓰고
            dfs(i+1,resultVal - numList[i])
            # 그거 진행하고
            sub += 1
            # 끝나면 다시 돌려주고
        if mul > 0:
            mul -= 1
            # 하기 전에 쓰고
            dfs(i+1,resultVal * numList[i])
            # 그거 진행하고
            mul += 1
            # 끝나면 다시 돌려주고
        if div > 0:
            div -= 1
            dfs(i+1, int(resultVal / numList[i]))
            # 그거 진행하고
            div += 1
            # 끝나면 다시 돌려주고

dfs(1, numList[0])

print(maxVal)
print(minVal)

기본 동작

 if add > 0:
 	add -= 1
	# 하기 전에 쓰고
	dfs(i+1, arr + numList[i])
	# 그거 진행하고
	add += 1
	# 끝나면 다시 돌려주고

dfs 의 기본 동작인(이전에 확실하게 이해하고 넘어갔잖아) 호출하기 전에 값 설정, 호출(동작), 호출하기 전으로 값 다시 원상복구

연산자와 다음 숫자에 대해 연산을 수행하고 그 값을 계속 기억하면서 진행한다

DFS, 무조건 간단 명료하게 모든 걸 아울러 풀 수 있는 로직을 짜는 것이 핵심, 잡다구리한 조건을 많이 넣을 수록 더 복잡해짐

/ , // 차이

print(int(105/6))
print(105//6)

위 코드 중 아래의 방식대로 하면 답이 다르게 나온다(틀린다)

왜 ?

/ => 나누기 연산하기, int로 소수점 버리기
// => 몫 구하기

예외가 있는건가?

print(int(105/6)) # 17
print(105//6)     # 17

print(int(-10/3)) # -3
print(-10//3) 	  # -4

# 나눠지는 값이 마이너스일 경우 예외

# -10 나누기 3은 -3.3333... 이다. 
#  '//' 연산자는 나누기 결과보다 작은 정수 중 가장 큰 정수인 -4를, 
# int() 연산자는 그냥 소수 부분을 버려서 -3을 결과로 갖는다.

0개의 댓글