[문제 풀이]

  • m 길이의 롤러로 페인트를 칠하기 때문에 (현재 벽을 칠하는 칸 + m - 1)칸 까지 벽이 칠해지게 됩니다.
  • 칠해야하는 제일 앞 칸 벽부터 칠하면서 함께 칠해진 벽을 같이 section에서 제외되도록 코드를 구성했습니다.

 

[문제 코드]

from collections import deque
def solution(n, m, section):
    answer = 0
    s = deque(section)
    while s:
        val = s[0]
        while s and val <= s[0] <= val + m-1:
            s.popleft()
        answer += 1
    return answer

컴퓨터 시스템은 다음과 같은 구성요소를 갖고 있습니다.

  • CPU(프로세서)
  • 메모리(Memory)
  • 레지스터(Register)
  • 버스(Bus)
  • 주변장치

CPU란?

컴퓨터의 중앙처리장치(Central Processing Unit, CPU)이며, 프로세서라고도 불립니다.

연산장치, 제어장치 그리고 레지스터로 구성되어 있으며 이를 통해 명령어를 해석하고 동작을 제어하며 연산을 수행합니다.

 

그래픽에 특화된 GPU(Graphic Processing Unit), 머신러닝에 특화된 (Tensor Processing Unit)이 있습니다.

 

*CPU가 유일하게 사용할 수 있는 데이터는 Memory에 존재하는 데이터 입니다.

따라서, 모든 프로그램은 Memory에 적재되어야 실행할 수 있습니다.

 

*CPU는 각 device controller에 "Command"만 전송 가능합니다.

각 장치로부터 데이터를 읽어올 수는 없습니다.


 메모리(Memory)란?

메모리는 데이터를 저장하는 공간입니다. 

크게 메인 메모리와 캐시로 구분됩니다.

 

  • 메인 메모리
    • CPU가 접근할 수 있는 유일한 저장 장치 입니다.
    • 저장된 데이터를 순차적으로 접근하는 것이 아닌 임의로 접근할 수 있습니다(Random access).
    • 저장된 데이터는 0과 1로 이루어져 있으며, 바이트 단위로 접근할 수 있습니다.
  • 캐시(Cache)
    • CPU의 처리 속도는 매우 빠른데 매번 메모리에 접근하여 데이터를 가져오는 것은 많은 시간을 소요할 수 있습니다. 이러한 간극을 해소하기 위해 나온 장치입니다.
    • 데이터 지역성(Locality)을 기반으로 동작합니다. (추후, 자세히 포스팅 하겠습니다.)
    • 메인 메모리의 일부 데이터를 미리 복사해두어서 프로세서가 빠르게 워드 단위의 데이터를 이용할 수 있습니다.

레지스터(Register)란?

CPU에 내장된 가장 작은 저장 장치입니다. CPU가 직접 접근할 수 있는 저장 장치이며, 캐시와 마찬가지로 CPU의 처리 속도 향상에 큰 영향을 미칩니다. 

 

저장 장치 중에 가장 빠른 속도를 지녔지만, 저장할 수 있는 용량은 32bit에서 64bit 사이의 작은 용량의 데이터만 저장할 수 있습니다.

 

*레지스터와 메모리의 가장 큰 차이점은, 레지스터는 CPU가 현재 처리하는 데이터를 가지고 있는 장치이고 메모리는 CPU가 필요한 데이터를 저장하고 있는 장치라는 점입니다.

 


버스(BUS)란?

CPU와 각 장치가 서로 데이터를 주고 받는 장치입니다.

위치와 기능에 따라 분류됩니다.

 

  • 위치에 따른 분류
    • 내부 버스: 프로세서 내부에서 연산장치 - 제어장치- 메모리 인터페이스 등을 연결해주는 장치입니다.
    • 외부 버스: 시스템 버스라고도 불립니다. 프로세서와 메모리, 프로세서와 외부 장치 등을 연결해주는 장치입니다.
  • 기능에 따른 분류
    • 제어 버스: 작업을 지시하는 신호가 오고 가는 장치로, 프로세서와 메모리 그리고 주변 장치에서 단방향으로 신호가 전송됩니다.
    • 데이터 버스: 데이터, 명령어 등을 전송하는 장치로, 프로세서와 메모리 그리고 주변 장치에서 양방향으로 신호가 전송됩니다. 일반적으로 데이터 버스의 신호선은 워드의 길이로 결정되며, 성능을 결정짓는 요소입니다.
    • 주소 버스: 작업을 수행할 때(메모리에 데이터 적재 등) 작업할 위치 정보를 전송하는 장치입니다.

주변 장치란?

모니터, 프린터, 스피커와 같이 입출력 장치등 컴퓨터에 연결되어 프로세서의 제어를 통해 동작하는 장치들을 총칭하는 단어입니다.

'CS > OS' 카테고리의 다른 글

[운영체제] Virtualization  (0) 2023.03.27
[운영체제] Interrupt  (0) 2023.03.17

[풀이 방법]

  • 각 자리 수를 모두 0으로 만들어주면 0으로 갈 수 있으므로, 각 자리 수를 0으로 만들거나 10으로 만들어서 0으로 만들었습니다.
  • ±10^c(c>=0)의 거리만큼 이동할 수 있으므로, 0으로 가는 것과 10으로 가는 것중 버튼을 적게 누르는 값을 answer에 더해주었습니다.(이때, 10으로 간다면 올림을 해주었습니다.)
  • 이때, 가장 문제가 되는 경우가 5인 경우였습니다. 5인 경우 0과 10까지의 거리가 동일하고, 올림할 다음 수가 5 이상인 경우 올림을 해야 더 적은 버튼을 누를 수 있으므로 올림하는 경우로 처리하였습니다.

 

[풀이 코드]

from collections import deque


def solution(storey):
    answer = 0
    q = deque([i for i in str(storey)[::-1]])
    roundup = 0

    while q:
        num = int(q.popleft())

        if roundup == 1:
            num += 1
            roundup = 0

        answer += num if 10 - num > num else 10 - num
        roundup = 1 if 10 - num < num else 1 if q and num == 5 and int(q[0]) >= 5 else 0

    return answer + 1 if roundup == 1 else answer

[풀이 방법]

  • 저는 문제를 풀 때, 실제로 두 좌표 간의 적분 값을 식으로 구해서 문제를 풀었습니다.
  • 다만, 문제를 다 풀고 나서 보니 두 좌표 (x1,y1) , (x2,y2) 가 있을 때, (y1+y2) / 2 한 값이 적분 값이 된다는 것을 알 수 있었습니다.(뒤늦게 깨달아버렸습니다..)

[풀이 코드]

# (앞의 좌표 + 뒤의 좌표 /2) 넓이가 나옴
def func(pos1, pos2):
    x1, y1 = pos1
    x2, y2 = pos2
    A = (y2 - y1) / (x2 - x1)

    return (A / 2 * (x2 ** 2 - x1 ** 2) + (y2 - A * x2) * (x2 - x1))


def solution(k, ranges):
    answer = []
    pos = [(0, k)]
    integral = []

    while k != 1:
        k = k // 2 if k % 2 == 0 else k * 3 + 1
        pos.append((pos[-1][0] + 1, k))

    # 한칸 구간별 적분 결과 구하기
    for idx in range(0, len(pos) - 1):
        integral.append(func(pos[idx], pos[idx + 1]))

    length = len(integral)
    for a, b in ranges:
        if -b > length - a:
            answer.append(-1)
        else:
            answer.append(sum(integral[a:length + b]))

    return answer

[문제 풀이]

  • sorted 함수를 통해 간단하게 풀 수 있었습니다. 코드와 같이 sorted 함수의 key에 lambda x : (x[col -1],-x[0]) 을 설정해주면 일차적으로 col번째 해당하는 값을 통해 정렬이 되는데, 해당 값이 같을 경우 제일 앞의 값(x[0])을 기준으로 정렬하게 됩니다. reverse를 설정해주지 않으면 오름차순 정렬이 이루어지므로, -x[0]을 활용할 경우 col번째 값이 같은 값들을 정렬할 때 내림차순 정렬이 이루어집니다.

 

[풀이 코드]

def solution(data, col, row_begin, row_end):
    data = sorted(data, key=lambda x: (x[col - 1], -x[0]))
    seq = []
    for i in range(row_begin - 1, row_end):
        s = 0
        for val in data[i]:
            s += val % (i + 1)
        seq.append(s)

    answer = seq[0]
    for i in range(1, len(seq)):
        answer = answer ^ seq[i]
    return answer

[문제 풀이]

  • 연산의 최소 횟수를 구해야하므로 bfs를 활용하였습니다.
  • 이때 연산된 값은 y보다 같거나 작아야하며, 거리가 구해진 적이 없어야만 갱신해주었습니다.(거리가 구해졌는지 여부와 상관 없이 값을 구하면 최소 연산 횟수를 구할 수 없습니다.)

[풀이 코드]

from collections import deque


def solution(x, y, n):
    answer = 0
    dq = deque([x])
    distance = [0 for _ in range(1000001)]

    if x == y:
        return 0
    while dq:
        val = dq.popleft()

        if 1 <= val * 2 <= y and distance[val * 2] == 0:
            distance[val * 2] = distance[val] + 1
            dq.append(val * 2)
        if 1 <= val * 3 <= y and distance[val * 3] == 0:
            distance[val * 3] = distance[val] + 1
            dq.append(val * 3)
        if 1 <= val + n <= y and distance[val + n] == 0:
            distance[val + n] = distance[val] + 1
            dq.append(val + n)

    return distance[y] if distance[y] != 0 else -1

[풀이 방법]

  • 틱택토에서 성립되지 않은 case를 찾았습니다.
    • 1. O가 완성 되었는데 X의 개수가 O의 개수와 같거나 더 많은 경우
    • 2. X가 완성 되었는데 O와 X의 개수가 다른 경우
    • 3. O와 X가 둘다 완성된 경우
    • 4. O의 갯수가 X의 개수보다 작거나 O의 개수가 X의 개수 + 1 보다 많은 경우
    • 이 문제에서 제일 시간을 많이 잡아먹은 경우는 4번 조건 이었습니다.  완성된 case가 없어도, O의 갯수는 항상 x의 개수와 같거나 더 많아야 하며, O의 개수가 X의 개수 + 1 보다 클 수 없습니다.
  • 그런 다음, 주어진 배열을 탐색하면서 수직 / 수평 / 대각선으로 만들어질 수 있는 case를 모두 찾았습니다.

 

[풀이 코드]

def get_count(board):
    o = 0
    x = 0

    for i in board:
        o += i.count('O')
        x += i.count('X')

    return (o, x)


def get_game_set(board, o, x):
    horizontal = []
    vertical = [''] * 3
    diagonal = [''] * 2

    for i in range(len(board)):
        diagonal[0] += board[i][i]
        diagonal[1] += board[2 - i][i]

    for i in range(len(board)):
        for j in range(len(board)):
            vertical[j] += board[i][j]

    for line in board:
        if line[0] == line[1] and line[1] == line[2]:
            horizontal.append(line[0] * 3)

    fin = horizontal + vertical + diagonal

    if 'OOO' in fin and 'XXX' in fin:
        return 0
    elif ('XXX' in fin and o != x):  # "XXX"만 완성되면 O와 X의 갯수는 동일해야한다
        return 0
    elif ('OOO' in fin and x >= o):  # "OOO"만 완성되면 O의 갯수는 무조건 X의 갯수보다 많아야한다.
        return 0

    return 1


def solution(board):
    o, x = get_count(board)
    if o < x or o > x + 1:
        return 0

    return get_game_set(board, o, x)

[풀이 방법]

  • 그래프 탐색 문제로 bfs 활용
  • 경유지가 있으므로, (시작점에서 경유지까지의 최단거리 + 경유지에서 끝점까지의 최단거리)를 계산
  • 미로를 탈출 할 수 없는 경우는 시작점에서부터 레버까지 도달하지 못하는 경우와 레버에서 끝점 까지 도달하지 못하는 경우가 있음

[풀이 코드]

from collections import deque


def search(r, c, maps, distance):
    visited = []
    direction = [(-1, 0), (1, 0), (0, -1), (0, 1)]

    q = deque([(r, c)])

    while q:
        x, y = q.popleft()

        if (x, y) in visited:
            continue
        visited.append((x, y))
        for dx, dy in direction:
            nx, ny = x + dx, y + dy

            if nx < 0 or nx >= len(maps) or ny < 0 or ny >= len(maps[0]) or maps[nx][ny] == 'X' or (nx, ny) in visited:
                continue
            distance[nx][ny] = distance[x][y] + 1
            q.append((nx, ny))


def solution(maps):
    answer = 0
    maps = [list(line) for line in maps]
    distance = [[0] * len(maps[0]) for _ in range(len(maps))]
    sr, sc, lr, lc, er, ec = 0, 0, 0, 0, 0, 0

    for i in range(len(maps)):
        if 'S' in maps[i]:
            sr, sc = i, maps[i].index('S')
        if 'L' in maps[i]:
            lr, lc = i, maps[i].index('L')
        if 'E' in maps[i]:
            er, ec = i, maps[i].index('E')

    search(sr, sc, maps, distance)
    if distance[lr][lc] == 0:
        return -1

    answer += distance[lr][lc]
    distance = [[0] * len(maps[0]) for _ in range(len(maps))]
    search(lr, lc, maps, distance)
    if distance[er][ec] == 0:
        return -1
    return answer + distance[er][ec] 

[풀이 방법]

  • 그래프 탐색을 통해 무인도를 탐색해준다.
  • 리스트 내의 값들이 string 형태이므로 list로 변환하여 사용하면 더 편하다.
  • 탐색 함수 안에서 조건문을 통해 list의 Index를 벗어나지 않도록 설정해준다.
  • 파이썬은 재귀함수의 깊이를 제한하므로 반복문을 통해 문제를 해결하거나, sys함수를 통해 깊이를 늘려줘야한다.

*이러한 문제 종류들을 만날 때, 항상 많이 헤메었었다. 리스트 내의 값을 확인 해야할 때는 '그래프 탐색'을 먼저 떠올릴 수 있으면 좋을 것 같다.

 

[풀이 코드]

import sys

sys.setrecursionlimit(1000000)


def search(maps, row, column, visited, value):
    if (row, column) in visited or 0 > row or row > len(maps) - 1 or column < 0 or column > len(maps[0]) - 1 or \
            maps[row][column] == 'X':
        return value
    value += int(maps[row][column])
    visited.append((row, column))
    value = search(maps, row - 1, column, visited, value)
    value = search(maps, row + 1, column, visited, value)
    value = search(maps, row, column - 1, visited, value)
    value = search(maps, row, column + 1, visited, value)

    return value


def solution(maps):
    answer = []
    visited = []
    maps = [list(Amap) for Amap in maps]
    value = 0

    for i in range(len(maps)):
        for j in range(len(maps[0])):
            if maps[i][j] == 'X' or (i, j) in visited:
                continue
            answer.append(search(maps, i, j, visited, value))

    return sorted(answer) if answer else [-1]

[풀이 방법]

  • List로 귤의 크기가 주어졌을 때, 최소한의 귤의 종류로 판매하고 싶은 갯 수를 채워야 하므로 Counter 함수를 통해 귤 크기 별로 갯 수를 구해준다.
  • 최소한의 종류로 판매하고자 하는 갯 수를 채우기 위해서는 갯 수가 많이 들어있는 크기의 귤을 활용하여 채워줘야 한다. 따라서, Counter의 most_common() 함수를 통해 정렬하여 문제 조건을 만족하는 귤 종류의 갯 수를 구한다.

 

[풀이 코드]

from collections import Counter


def solution(k, tangerine):
    answer = 0
    dic = Counter(tangerine)

    for i in dic.most_common():
        answer += 1
        k -= i[1]
        if k <= 0:
            break

    return answer

+ Recent posts