9372_상근이의 여행 (Python)

0. 출처

1. 기록

  • 22/04/18 (월)

2. 풀이

(1) 아이디어, 시간복잡도, 자료구조

1. 아이디어
>> 

2. 시간복잡도
>>

3. 자료구조
>>

(2) 예제 입력, 예제 출력

- 예제 입력 1 -
2 (테스트 케이스 수)
3 3 (국가의 수 / 비행기의 종류)
1 2
2 3
1 3
5 4 (국가의 수 / 비행기의 종류)
2 1
2 3
4 3
4 5

- 예제 출력 1 -
2
4

(3) 코드

sample

(4) 정리

문제를 잘 못읽어 예제입력 예제출력이 왜 저렇게되나 한참봤다..
왜 예제출력 결과가 2개나 나오는지 때문에.. (맨 처음에 주어진게 테스트 케이스였음)
문제를 잘 읽자

또한 모든 국가가 연결되어있기 때문에 모든 국가를 방문하려면 국가의 갯수 - 1 이 정답이다.

(5) 참고

참고 풀이

9934_완전 이진 트리 (Python)

0. 출처

1. 기록

  • 22/04/18 (월)

2. 풀이

(1) 아이디어, 시간복잡도, 자료구조

1. 아이디어
>> 문제에서 주어진 방문순서는 중위 순회이다.
>> 레벨과 방문순서가 주어진다.
>> 주어진 것으로 트리의 정보를 구해야 한다.
>> 어떻게 구하지..?

>> 중위순회를 반대로 실행해야 한다.
>> level 활용하기
>> 중위순회 입력된 리스트 가운데가 항상 root 노드임을 활용하기
>> 중위 순회로 입력된 리스트를 왼쪽 부분 트리, 오른쪽 부분 트리로 쪼갤 줄 알아야한다.

2. 시간복잡도
>>

3. 자료구조
>>

(2) 예제 입력, 예제 출력

- 예제 입력 1 -
2
2 1 3

- 예제 출력 1 -
1
2 3

- 예제 입력 2 -
3
1 6 4 3 5 2 7

- 예제 출력 2 -
3
6 2
1 4 5 7

(3) 코드

k = int(input())
inorder = list(map(int, input().split()))

answer = [[] for _ in range(k)]

def dfs(inorder, depth):

    # 트리의 root index를 찾아낸다.
    mid = (len(inorder) // 2)

    # 해당 깊이에 해당하는 node를 추가한다.
    answer[depth].append(inorder[mid])

    if len(inorder) == 1:
        return

    dfs(inorder[:mid], depth+1)
    dfs(inorder[mid+1:], depth+1)

dfs(inorder, 0)

for i in answer:
    print(*i)

(4) 정리

(5) 참고

참고 풀이

9934_[문제이름] (Python)

0. 출처

1. 기록

  • 22/04/18 (월)

2. 풀이

(1) 아이디어, 시간복잡도, 자료구조

1. 아이디어
>> 문제에서 주어진 방문순서는 중위 순회이다.
>> 레벨과 방문순서가 주어진다.
>> 주어진 것으로 트리의 정보를 구해야 한다.
>> 어떻게 구하지..?

>> 중위순회를 반대로 실행해야 한다.

2. 시간복잡도
>>

3. 자료구조
>>

(2) 예제 입력, 예제 출력

- 예제 입력 1 -
2
2 1 3

- 예제 출력 1 -
1
2 3

- 예제 입력 2 -
3
1 6 4 3 5 2 7

- 예제 출력 2 -
3
6 2
1 4 5 7

(3) 코드

sample

(4) 정리

(5) 참고

참고 풀이

1991_트리 순회 (Python)

0. 출처

1. 기록

  • 22/04/18 (월)

2. 풀이

(1) 아이디어, 시간복잡도, 자료구조

1. 아이디어
>> 각 노드, 왼쪽 노드, 오른쪽 노드가 주어졌을 때
>> 어떻게 tree 에 저장할 것인지?
>> set() 형태로 저장해보자.

2. 시간복잡도
>>

3. 자료구조
>>

(2) 예제 입력, 예제 출력

- 예제 입력 1 -
7
A B C
B D .
C E F
E . .
F . G
D . .
G . .

- 예제 출력 1 -
ABDCEFG
DBAECFG
DBEGFCA

(3) 코드

n = int(input())

tree = {}

for _ in range(n):
    node, left, right = map(str, input().split())
    tree[node] = [left, right]

def preorder(root):              # 전위순회
    if root != '.':
        print(root, end='')      # root
        preorder(tree[root][0])  # left
        preorder(tree[root][1])  # right

def inorder(root):               # 중위순회
    if root != '.':
        inorder(tree[root][0])   # left
        print(root, end='')      # root
        inorder(tree[root][1])   # right

def postorder(root):             # 후위순회
    if root != '.':
        postorder(tree[root][0]) # left
        postorder(tree[root][1]) # right
        print(root, end='')      # root

preorder('A')
print()        # 줄바꿈 용도
inorder('A')
print()        # 줄바꿈 용도
postorder('A')

(4) 정리

재귀를 잘 이해해야 이해할 수 있는 풀이이다.

전위 순회, 중위 순회, 후위 순회 개념이 코드에 그대로 적용된 풀이이다.

(5) 참고

참고 풀이

[문제번호]_[문제이름] (Python)

0. 출처

1. 기록

  • 22/04/18 (월)

2. 풀이

(1) 아이디어, 시간복잡도, 자료구조

1. 아이디어
>> 루트노드가 1인 정보가 주어져있다.
>> 그 외의 나머지는 연결관계만 주어져있다.
>> 이 경우 부모노드를 어떻게 파악하면 좋을까?
>> 우선 연결관계부터 만들어보자.

2. 시간복잡도
>>

3. 자료구조

(2) 예제 입력, 예제 출력

- 예제 입력 1 -
7
1 6
6 3
3 5
4 1
2 4
4 7

- 예제 출력 1 -
4
6
1
3
1
4

- 예제 입력 2 -
12
1 2
1 3
2 4
3 5
3 6
4 7
4 8
5 9
5 10
6 11
6 12

- 예제 출력 2 -
1
1
2
3
3
4
4
5
5
6
6

(3) 코드

import sys

sys.setrecursionlimit(10**9)

n = int(input())

# 트리
tree = [[] for _ in range(n+1)]

# 부모 노드 저장
relation = [0 for _ in range(n+1)]

for _ in range(n-1):
    a, b = map(int, input().split())
    tree[a].append(b)
    tree[b].append(a)

def dfs(start, tree, relation):
    # 연결된 노드들부터 relation[i] 의 부모가 없으면 부모 설정해주고 dfs를 돌린다.
    for node in tree[start]:
        if relation[node] == 0:
            # node에게 너 여기서 출발했다고 표시해주는 느낌
            relation[node] = start
            dfs(node, tree, relation)

dfs(1, tree, relation)

for i in range(2, n+1):
    print(relation[i])

(4) 정리

(5) 참고

참고 풀이

18430_[문제이름] (Python)

0. 출처

1. 기록

  • 22/04/11 (월)

2. 풀이

(1) 아이디어, 시간복잡도, 자료구조

1. 아이디어
>> 특정 3칸을 차지하면 나머지 칸에서 ㄱ or ㄴ 형태로 3칸을 차지하는 모든 경우를 체크해서 
>> 문제에서 요구하는 사항에 맞는 최댓값을 갱신시킨다.
>> 특정 3칸을 이동하고 다시 반복
>> 특정 3칸 ㄱ or ㄴ 형태를 어떻게 입력시킬 것인지?
>> ┌, ┐, └, ┘ 각 4가지 모양을 기준으로 위의 로직을 반복한다.

2. 시간복잡도
>>

3. 자료구조
>>

(2) 예제 입력, 예제 출력

- 예제 입력 1 -
3 3
32 83 75
24 96 56
71 88 12

- 예제 출력 1 -
632

- 예제 입력 2 -
1 1
7

- 예제 출력 2 -
0

(3) 코드

# (0,0)부터 시작
# 시작점을 방문안했으면
#   부메랑 블럭이 범위 안에 있고, 방문안했으면 --> 강도 계산
# 시작점을 방문했으면
#   시작점 = 한칸 옆
def first(y, x):
    return woods[y][x-1] + 2*woods[y][x] + woods[y-1][x]


def second(y, x):
    return woods[y][x-1] + 2*woods[y][x] + woods[y+1][x]


def third(y, x):
    return woods[y+1][x] + 2*woods[y][x] + woods[y][x+1]


def fourth(y, x):
    return woods[y-1][x] + 2*woods[y][x] + woods[y][x+1]


def solve(y, x, strength):
    global N, M, answer
    if x == M:
        x = 0
        y += 1
    if y == N:
        answer = max(answer, strength)
        return
    if not visited[y][x]:
        if y - 1 >= 0 and x - 1 >= 0 and not visited[y][x-1] and not visited[y-1][x]:
            visited[y][x] = visited[y][x-1] = visited[y-1][x] = True
            this_strength = strength + first(y, x)
            solve(y, x+1, this_strength)
            visited[y][x] = visited[y][x-1] = visited[y-1][x] = False
        if y + 1 < N and x - 1 >= 0 and not visited[y+1][x] and not visited[y][x-1]:
            visited[y][x] = visited[y][x-1] = visited[y+1][x] = True
            this_strength = strength + second(y, x)
            solve(y, x+1, this_strength)
            visited[y][x] = visited[y][x-1] = visited[y+1][x] = False
        if y + 1 < N and x + 1 < M and not visited[y+1][x] and not visited[y][x+1]:
            visited[y][x] = visited[y][x+1] = visited[y+1][x] = True
            this_strength = strength + third(y, x)
            solve(y, x+1, this_strength)
            visited[y][x] = visited[y][x+1] = visited[y+1][x] = False
        if y - 1 >= 0 and x + 1 < M and not visited[y-1][x] and not visited[y][x+1]:
            visited[y][x] = visited[y][x+1] = visited[y-1][x] = True
            this_strength = strength + fourth(y, x)
            solve(y, x+1, this_strength)
            visited[y][x] = visited[y][x+1] = visited[y-1][x] = False
    solve(y, x+1, strength)


N, M = map(int, input().split())
woods = [list(map(int, input().split())) for _ in range(N)]
visited = [[False] * M for _ in range(N)]
answer = 0
solve(0, 0, 0)
print(answer)

(4) 정리

아이디어는 맞았으나 구현을 제대로 못해 해답을 찾아본 문제입니다.
구체적으로 visited 등에 ┌, ┐, └, ┘등 각 모양을 체크 후 재귀를 구현하는걸 세세히 코드화시키지 못하였습니다.
구현력 기르는 연습을 계속해야할 듯 합니다.

(5) 참고

참고 풀이1
참고 풀이2
참고 풀이3

1174__줄어드는 수 (Python)

0. 출처

1. 기록

  • 22/04/10 (일)

2. 풀이

(1) 아이디어, 시간복잡도, 자료구조

1. 아이디어
>> 예제 입력과 예제 출력을 보고 뭔말인지 도저히 모르겠음
>> 문제 이해 함
>> 문제 조건에 맞는 1번째로 가장 작은수는 0
>> 2번째로 가장 작은 수는 1
>> 3번째로 가장 작은 수는 2
>> ...
>> 10번째로 가장 작은 수는 9
>> 11번째로 가장 작은 수는 10
>> 12번째로 가장 작은 수는 20

>> 그래서 어떻게 풀건데? 
>> 마지막 값 > 현재 값 경우, 재귀 진행하여 감소하는 수를 만들어 준다.
>> 감소하는 수를 정렬한다.

2. 시간복잡도
>>

3. 자료구조
>>

(2) 예제 입력, 예제 출력

- 예제 입력 1 -
sample

- 예제 출력 1 -
sample

(3) 코드

n = input()
arr = list()
result = list()

def dfs():
    if len(arr) > 0:
        result.append(int("".join(map(str, arr))))

    for i in range(0, 10):
        if len(arr) == 0 or arr[-1] > i:  # 마지막 값이 더 큰 경우
            arr.append(i)
            print(arr)
            dfs()
            arr.pop()

try:
    dfs()
    result.sort()
    print(result[n - 1])
except:
    print(-1)

(4) 정리

처음에 문제가 이해가 안가서 답안 코드에 1부터 하나하나 집어넣고 이해했다.

문제 이해력을 길러야겠다.

(5) 참고

참고 풀이

16235_나무 재테크 (Python)

0. 출처

1. 기록

  • 22/04/07 (목)

2. 풀이

(1) 아이디어, 시간복잡도, 자료구조

'''
1. 아이디어
>>
>>

2. 시간복잡도
>>

3. 자료구조
>>
'''

(2) 예제 입력, 예제 출력

- 예제 입력 1 -
sample

- 예제 출력 1 -
sample

(3) 코드

sample

(4) 정리

(5) 참고

참고 풀이

15685_드래곤 커브 (Python)

0. 출처

1. 기록

  • 22/04/07 (목)

2. 풀이

(1) 아이디어, 시간복잡도, 자료구조

'''
1. 아이디어
>>
>>

2. 시간복잡도
>>

3. 자료구조
>>
'''

(2) 예제 입력, 예제 출력

- 예제 입력 1 -
sample

- 예제 출력 1 -
sample

(3) 코드

sample

(4) 정리

0 세대 - 0

1 세대 - 0 1

2 세대 - 0 1 2 1

3 세대 - 0 1 2 1 2 3 2 1

4 세대 - 0 1 2 1 2 3 2 1 2 3 0 3 2 3 2 1

다음 세대는 이전 세대의 '역방향'으로 +1 한 방향을 나타내게 된다. (문제에서 핵심이 되는 규칙성★)
(사람들이 이러한 규칙성을 봤다는게 신기함..)

또한 세대가 증가할 때, 선분의 갯수가 공비가 2인 등비 수열인 것을 파악할 수 있다.
이것으로 배열의 크기를 추측 및 설정할 수 있다.

단순 이중 반복문을 통해 네 꼭짓점이 드래곤 커브로 만들어졌는지 확인하면 된다.
주의할 점은 x, y 방향으로 벽에 도달했을 때는 탐색할 수 없다는 것이다.

(5) 참고

문제 이해1
문제 이해2

14888_연산자 끼워넣기 (Python)

0. 출처

1. 기록

  • 22/04/03 (일)

2. 풀이

(1) 아이디어, 시간복잡도, 자료구조

'''
1. 아이디어
>>
>>

2. 시간복잡도
>>

3. 자료구조
>>
'''

(2) 예제 입력, 예제 출력

- 예제 입력 1 -
sample

- 예제 출력 1 -
sample

(3) 코드

# 백트래킹 (Python3 통과, PyPy3도 통과)
import sys

N = int(input())
num = list(map(int, input().split()))
op = list(map(int, input().split()))  # +, -, *, //

maximum = -1e9
minimum = 1e9


def dfs(depth, total, plus, minus, multiply, divide):
    global maximum, minimum
    if depth == N:
        maximum = max(total, maximum)
        minimum = min(total, minimum)
        return

    if plus:
        dfs(depth + 1, total + num[depth], plus - 1, minus, multiply, divide)
    if minus:
        dfs(depth + 1, total - num[depth], plus, minus - 1, multiply, divide)
    if multiply:
        dfs(depth + 1, total * num[depth], plus, minus, multiply - 1, divide)
    if divide:
        dfs(depth + 1, int(total / num[depth]), plus, minus, multiply, divide - 1)


dfs(1, num[0], op[0], op[1], op[2], op[3])

print(maximum)
print(minimum)

(4) 정리

(5) 참고

참고 풀이

+ Recent posts