# Selection Sort
# 앞에서부터 원소를 하나씩 선택한 후, 그 뒷부분에서 최솟값을 찾아 그 둘을 swap하는방식으로 정렬하는 방식
# 시간복잡도: O(N^2) <- N(N-1)/2
# 공간복잡도: n
# 장점: 비교횟수는 많지만 bubble sort에 비해 자리를 교환하는 횟수가 적어 많은 교환이 일어나야 할 때(정렬이 많이 이루어져야 할 때) 효율적
# 추가 메모리를 필요로 하지 않는다(in-place). 
# 단점: unstable하다.

 

Python

def selection_sort(lst):
    for i in range(len(lst)-1):  # i = 정렬할 자리. 맨 마지막은 안 봐도 됨
        min_idx = i  # min_idx 은 i와 swap할 원소
        for j in range(i+1, len(lst)):
            if lst[min_idx] > lst[j]:
                min_idx = j
        lst[i], lst[min_idx] = lst[min_idx], lst[i]  # i 자리에 min_idx의 원소를 넣고 swap
    return lst

arr = [3, 9, 3, 1, 5]  # unstable의 예
print(selection_sort(arr))

 

Javascript

function selection_sort(arr) {
    for (let i=0; i<arr.length-1; i++) {
        let min_idx = i;
        for (let j=i+1; j<arr.length; j++) {
            if (arr[min_idx] > arr[j]) min_idx = j;
        }
        let tmp = arr[i];
        arr[i] = arr[min_idx];
        arr[min_idx] = tmp;
    }
    
    return arr;
}

'CS > 알고리즘' 카테고리의 다른 글

Insertion Sort in Python (삽입 정렬)  (0) 2020.06.09
크루스칼 알고리즘 (Python)  (0) 2020.05.07
프림 알고리즘 (Python)  (0) 2020.05.07
Call by Value vs Call by Reference  (0) 2020.04.28
Bubble Sort (버블 정렬)  (0) 2020.04.24
def bubble(lst):
    for i in range(len(lst)-1):
        if lst[i] > lst[i+1]:
            lst[i], lst[i+1] = lst[i+1], lst[i]
	

a = [3, 1, 5, 9, 7, 10]
bubble(a)
print(a)
	

# Bubble Sort
# 서로 인접한 두 원소의 대소를 비교해가면서 자리를 교환해 정렬하는 방식
# 시간복잡도: O(n^2)
# 공간복잡도: n
# 장점: 구현이 쉽다. memory가 추가로 들지 않는다(in-place). 중복된 값들이 있을 경우 원래 순서를 보장한다(stable).
# 단점: 정렬이 되어 있건 안 되어 있건 무조건 비교 연산을 수행하기 때문에 수행시간이 무조건 n^2이다.

'CS > 알고리즘' 카테고리의 다른 글

Insertion Sort in Python (삽입 정렬)  (0) 2020.06.09
크루스칼 알고리즘 (Python)  (0) 2020.05.07
프림 알고리즘 (Python)  (0) 2020.05.07
Call by Value vs Call by Reference  (0) 2020.04.28
Selection Sort (선택 정렬)  (0) 2020.04.24

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV597vbqAH0DFAVl&

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

 

 

def calc(dict):
    total = 0
    for rc, val in dict.items():
        total += val[NUM]
    return total


def solve():
    global virus
    for _ in range(M):  # M 시간 뒤의 결과를 구해야 함
        new = {}  # 이동을 마친 바이러스를 넣을 딕셔너리

        # 이동
        for rc, val in virus.items():
            num, direct, _ = val
            next_row = rc[0] + dx[direct-1]
            next_col = rc[1] + dy[direct-1]
            if next_row == 0 or next_row == N-1 or next_col == 0 or next_col == N-1:
                if direct == 1:
                    direct = 2
                elif direct == 2:
                    direct = 1
                elif direct == 3:
                    direct = 4
                elif direct == 4:
                    direct = 3
                num = num // 2
                
                if num == 0:
                    continue

            if (next_row, next_col) not in new:
                new[(next_row, next_col)] = [num, direct, num]
            else:
                if num > new[(next_row, next_col)][MAX]:  # 맥스 num보다 크면 direct를 교체
                    new[(next_row, next_col)][DIRECT] = direct
                    new[(next_row, next_col)][MAX] = num  # max 교체
                new[(next_row, next_col)][NUM] += num

        virus = new
    return calc(virus)


NUM, DIRECT, MAX = 0, 1, 2
T = int(input())
dx = (-1, 1, 0, 0)
dy = (0, 0, -1, 1)
for i in range(T):
    N, M, K = map(int, input().split())  # 격자의 크기 N, 시간 M, 군집의 갯수 K
    virus = {}
    for _ in range(K):
        x, y, n, d = map(int, input().split())  # 가로, 세로, 군집크기, 방향
        virus[(x, y)] = [n, d, n]  # 군집 크기, 방향, max(같은 셀에 모인 군집 중 가장 큰 크기. 현재는 자기 뿐이므로 자기 자신의 크기 n)

    print("#{} {}".format(i+1, solve()))

'알고리즘 > 시뮬레이션' 카테고리의 다른 글

17822번. 원판 돌리기  (0) 2020.05.02
17140번. 이차원 배열과 연산  (0) 2020.04.27
17144번. 미세먼지 안녕!  (0) 2020.04.21
16235번. 나무 재테크  (0) 2020.04.20
15685번. 드래곤 커브  (0) 2020.04.16
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
a = b  # 얕은 복사(주소 같음)
print("a의 주소:", id(a))
print("b의 주소:", id(b))

b = [100, 100, 100, 100]  # b를 새로운 객체로 대체하면

print("a:", a)
print("a의 주소:", id(a))  # a의 값에는 영향이 없고,
print("b의 주소:", id(b))  # b는[100, 100, 100, 100] 이라는 새로운 객체를 가리킴


# 평범한 shallow copy를 보여주는 예
a = b
b[0] = 0
print(a)

결과

a = b를 하면, a -> b -> [리스트]가 아니라

a -> [리스트] <- b 가 되므로, 

b에게 다른 값을 넣어도

a -> [리스트]

b -> [다른리스트]

가 되는 거다.

'알고리즘 > 그외중요한것들' 카테고리의 다른 글

완주하지 못한 선수 (Python)  (0) 2020.07.03
2252번. 줄 세우기  (0) 2020.05.11
2003번. 수들의 합 2  (0) 2020.03.30

http://boj.kr/17144

 

17144번: 미세먼지 안녕!

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사과는 뛰어난 코딩 실력을 이용해 각 칸 (r, c)에 있는 미세먼지의 양을 실시간으로 모니터링하는 시스템을 개발했다. (r, c)는 r행 c열을 의미한다. 공기청정기는 항상 1번 열에 설치되어 있고, 크기는 두 행을 차지한다. 공기청정기가 설치되어 있지 않은 칸에는 미세먼

www.acmicpc.net

 

 

 

모든 미세먼지가 '동시에' 확산한다고 해서 BFS인가 했더니만 그냥 배열 크기만큼 돌면서 시뮬레이션해주는 문제였다.

RxC을 돌며 4방향 확산->공기청정기의 순환->RxC을 돌며 4방향 확산->공기청정기의 순환

이 과정을 T만큼 반복해야 한다.

 

주의해야 할 점은 모든 미세먼지는 동시에 확산된다는 점이다.

즉, 한 번의 로테이션 동안에는 서로 영향을 줘서는 안된다.

주변으로 확산될 미세먼지를 주변에 바로 더하면 안되고 따로 저장해둔 뒤에, 한꺼번에 확산시켜야 된다는 것이다.

(r, c)에서 미세먼지가 확산되버리면 다음 반복문인 (r, c+1)의 미세먼지 양을 계산할 때 영향을 주기 때문이다. 

나는 room[R][C] = [현재 미세먼지, 다음번에 주변으로 확산될 미세먼지] 로 저장했다. 

일단 한번 RxC를 돌면서 현재 미세먼지를 전부 계산한 후에, 다시한번 처음부터 RxC를 돌면서 저장된 미세먼지를 주변으로 확산시켰다.

 

공기청정기로 인한 미세먼지의 이동은 BFS 때처럼 배열을 만들어놓고 range로 총 4번 방향을 꺾게 하는 방법,

아니면 직접 총 8번의 for문으로 구역을 나누어서 이동시키는 방법이 있다.

나는 전자의 방법으로 처음에 시도했는데 하다보니 헷갈려서 시간을 너무 오래 썼다.

보다 간단하고 디버깅도 구역별로 나눠서 가능한 후자가 더 나을 것 같다.

(코드 내에서 전자의 방법은 air_fresh_upside & air_fresh_downside 함수이고

후자의 방법은 73-83번 줄의 for문이다. 윗부분만 for문으로 했기 때문에 4줄이다.)

 

전자이든 후자이든, 중요한 것은 공기청정기에 들어온 미세먼지는 사라진다는 것인데,

이것은 바꿔말하면 공기청정기 다음 위치(문제에서 보면 col + 1 한 곳)에 0이 들어온다는 뜻이 된다.

하지만 헷갈려서 공기청정기 이전 위치를 0으로 바꾼다던가 공기청정기를 다시 -1로 돌려놓지 않는다던가 하는 일이 발생하게 된다...

항상 초록색 네모가 0이 된다고 생각하면 된다.

 

import sys


def Print(lst):
    for i in lst:
        for j in i:
            print(j[0], end=' ')
        print("")
    print("")


def air_fresh_upside(r, c):
    dx = [-1, 0, 1, 0]
    dy = [0, 1, 0, -1]

    for d in range(4):
        while True:
            if 0 <= r + dx[d] <= head_loc[0] and 0 <= c + dy[d] < C:
                if room[r+dx[d]][c+dy[d]][0] == -1:
                    room[r][c][0] = 0
                    break
                else:
                    room[r][c][0] = room[r+dx[d]][c+dy[d]][0]
                r += dx[d]
                c += dy[d]
            else:
                break
    room[head_loc[0]][head_loc[1]][0] = -1


def air_fresh_downside(r, c):
    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]

    for d in range(4):
        while True:
            if tail_loc[0] <= r + dx[d] < R and 0 <= c + dy[d] < C:
                if room[r+dx[d]][c+dy[d]][0] == -1:
                    room[r][c][0] = 0
                    break
                else:
                    room[r][c][0] = room[r + dx[d]][c + dy[d]][0]
                r += dx[d]
                c += dy[d]
            else:
                break
    room[tail_loc[0]][tail_loc[1]][0] = -1


def solve():
    for _ in range(T):
        for r in range(R):
            for c in range(C):
                if room[r][c][0] >= 5:  # 미세먼지가 5 이상이면 확산함
                    dust_num = 0
                    for dr, dc in [[0, 1], [0, -1], [1, 0], [-1, 0]]:  # 상하좌우
                        if 0 <= r + dr < R and 0 <= c + dc < C:  # room 범위 내에서 &
                            if room[r+dr][c+dc][0] != -1:  # 공기청정기 영역이 아니라면 확산
                                dust_num += 1
                                room[r+dr][c+dc][1] += room[r][c][0] // 5
                    room[r][c][0] = room[r][c][0] - (room[r][c][0]//5) * dust_num

        # 확산된 미세먼지(room[r][c][1])를 기존 미세먼지에(room[r][c][0]) 합친다
        for r in range(R):
            for c in range(C):
                room[r][c][0] += room[r][c][1]
                room[r][c][1] = 0

        # 미세먼지의 이동 (방법 1)
        #air_fresh_upside(head_loc[0]-1, head_loc[1])
        air_fresh_downside(tail_loc[0]+1, tail_loc[1])

        # 미세먼지 이동 (방법 2)
        for i in range(0, C-1):
            room[0][i][0] = room[0][i+1][0]
        for i in range(0, head_loc[0]+1):
            room[i][C-1][0] = room[i+1][C-1][0]
        for i in range(0, C-1):
            room[head_loc[0]][C-1-i][0] = room[head_loc[0]][C-2-i][0]
        for i in range(0, head_loc[0]):
            room[head_loc[0]-i][0][0] = room[head_loc[0]-1-i][0][0]
        room[head_loc[0]][head_loc[1]+1][0] = 0
        room[head_loc[0]][head_loc[1]][0] = -1

        #Print(room)

    # sum
    ret = 0
    for r in range(R):
        for c in range(C):
            ret += room[r][c][0]
    return ret + 2


input = sys.stdin.readline
R, C, T = map(int, input().split())
room = [list(map(int, input().split())) for _ in range(R)]
head_loc, tail_loc = [], []  # 공기청정기 윗부분. 아랫부분 위치

for i in range(R):
    for j in range(C):
        if room[i][j] == -1:
            if head_loc:
                tail_loc = [i, j]
            else:
                head_loc = [i, j]
        room[i][j] = [room[i][j], 0]  # [현재 미세먼지, 다음에 확산되서 합쳐질 미세먼지]

print(solve())

'알고리즘 > 시뮬레이션' 카테고리의 다른 글

17140번. 이차원 배열과 연산  (0) 2020.04.27
SWEA 2382번. 미생물 격리  (0) 2020.04.24
16235번. 나무 재테크  (0) 2020.04.20
15685번. 드래곤 커브  (0) 2020.04.16
14891번. 톱니바퀴  (0) 2020.04.13

http://boj.kr/15971 

 

 

최단거리를 찾는 문제이다. 하지만 BFS가 아닌 DFS로 찾아야 한다. 그 이유는 경로는 단 하나이기 때문이다. BFS로 하면 시간초과가 난다.

경로를 DFS로 풀면서 헷갈린 점이 있는데, 이리저리 경로를 헤매는 BFS 같은 경우가 아니므로 visited를 다시 체크해제할 필요가 없다는 것이다.

한번 방문한 점은 다시 방문하지 않을 것이다. 왜냐면 어떤 한 점으로 가는 방법은 하나이기 때문이다. 다른 루트를 통해 그 점으로 갈 수 없다는 뜻이다.

 

그리고 경로는 단 하나이므로, 출발지에서 목적지까지 가는 경로를 구한 후, 하나의 weight를 뺄 수 있으므로 가장 큰 weight을 빼주면 된다. 두 로봇들이 가장 긴 통로를 사이에 두고 ㅇㅡㅇ 통신을 한다고 보면 된다. 그리고 그 를 가장 긴 통로로 선택하면 되고.

 

방법은 이렇지만 파이썬으로 풀기 까다로운 문제인데, 시간초과와 메모리초과가 나기 때문이다.

경로를 N * N의 배열에 저장하면 dfs로 경로 선택을 할 때 매번 N번만큼 반복하게 되므로 시간초과가 난다.

그리고 dfs를 할 때 재귀가 아닌 스택으로 풀면 시간 초과가 난다. (N <= 5000 일때만 통과)

또 재귀를 할 때도 반드시 sys.setrecursionlimit(500000000) 를 넣어줘야 한다.

 

마지막으로 문제에서 점은 1부터 시작한다고 했으므로 점을 입력받은 후 배열 인덱스로 쓰기 전에 -1을 하던가, 배열을 하나 더 크게 만들던가 해야된다는 점을 잊지 말자.

import sys


def dfs(now, max_weight, total):
    if now == end-1:
        print(total - max_weight)
        exit(0)
    for next, d in dist[now]:
        if not visited[next]:
            visited[next] = 1
            dfs(next, max(max_weight, d), total+d)


def dfs_stack():
    stack = [[start-1, 0, 0]]
    while stack:
        now, max_weight, total = stack.pop()
        if now == end - 1:
            print(total - max_weight)
            break
        for next, d in dist[now]:
            if not visited[next]:
                visited[next] = 1
                stack.append([next, max(max_weight, d), total+d])

sys.setrecursionlimit(500000000)

input = sys.stdin.readline
N, start, end = map(int, input().split())
dist = [[] for _ in range(N)]
visited = [0] * N

for _ in range(N-1):
    i, j, d = map(int, input().split())  # 왼쪽방, 오른쪽방, 거리
    dist[i-1].append([j-1, d])  # dist[왼쪽점] = [오른쪽점, 거리]
    dist[j-1].append([i-1, d])  
    # dist[왼쪽점][오른쪽점] = 거리 <- 거리를 dist[N][N]으로 만들면 
    # dfs에서 다음 점을 선택할 때 for문이 무조건 N번 돌아야해서 시간초과
    # dist[왼쪽점][오른쪽점] = 0 인 곳은 빼고 탐색할 수 있도록 해야 한다.

visited[start-1] = 1
dfs(start-1, 0, 0)
#dfs_stack()

'알고리즘 > BFS와 DFS' 카테고리의 다른 글

programmers. 네트워크 (python)  (0) 2020.05.18
17142번. 연구소 3  (0) 2020.04.26
14501번. 퇴사  (0) 2020.04.17
16236번. 아기 상어  (0) 2020.04.13
2178번. 미로 탐색  (0) 2020.04.08

http://boj.kr/16235 

 

 

각 계절별로 아래와 같은 행위를 정의한 다음 함수로 만들고 k년마다 실행하면 된다.

 

봄: 각 칸에 있는 나무들이 양분을 섭취하거나 죽은 나무 리스트에 추가된다.

여름: 죽은 나무들이 그 나이의 절반만큼 양분으로 추가된다.

가을: 어떤 나무의 나이가 5의 배수라면, 인접한 8칸에 1의 나이를 가진 나무들이 추가된다.

겨울: 모든 나무들에게 각기 주어진 만큼의 양분을 추가한다.

 

각 계절별로 따로 함수를 만들어도 되지만 가을, 겨울은 서로 영향을 주지 않기 때문에 하나의 반복문 내에서 실행되도록 했다.

53번줄처럼 밭을 board[N][N]으로,

1x1 크기의 각 칸은 [양분, [그 칸에 있는 나무들의 나이], 죽은 나무 나이/2, 나무의 숫자]로 정해주었고 

각 칸의 인덱스를 0~3으로 접근하면 헷갈리기 때문에 MEAL, TREE, DEAD, NUM = 0, 1, 2, 3으로 define해주었다.

nutrition이 아니라 meal인 이유는 nutrition은 너무 길기 때문에...

 

위에서 설명한 것처럼 board 배열을 3차원으로 초기화하려면 주의해야할 것이 있다.

보통 2차원 배열을 초기화할 때 [0] * N for _ in range(N) 이라는 방법을 쓴다.

나는 여기서 [0]  ->  [양분, [그 칸에 있는 나무들의 나이], 죽은 나무 나이/2, 나무의 숫자] 라고 생각해서

단순히  [[[양분, [그 칸에 있는 나무들의 나이], 죽은 나무 나이/2, 나무의 숫자]] * N for _ in range(N)] for _ in range(N)]이라고 해주었었다. 문제가 되는 부분은 볼드처리 된 부분으로, 저것은 배열이기 때문에 * N 으로 만들면 안 된다! 저렇게 하면 하나의 배열 객체가 만들어진후에 N 개만큼 자가증식한다. 하나가 바뀌면 N 개의 형제들이 모두 값이 바뀌게 된다. shallow copy인 셈이다.

 

파이썬은 1.3초의 시간을 주긴 하지만, 기본적으로 0.3초의 시간 밖에 주지 않아서 시간을 최대한 줄이기 위해 deque를 썼다. 작은 나무 먼저 양분을 먹는다고 했으므로, 우선 입력을 받은 후에 나무 배열을 sort()로 정렬한다. 

그 이후에 나무들을 차례대로 보면서 양분을 먹이거나 죽이거나 하는 과정은 

28번줄에서 popleft로 맨 앞에 있는 가장 어린 나무를 꺼낸 후 

31번째줄에서 맨 뒤에 다시 추가시켜 주는 식으로 반복했다. 이것을 나무의 갯수(NUM)만큼 진행하면 된다.

매번 새로 정렬해야했다면 spring()에서만 시간이 2배로 걸렸을 것이다.

import sys
from collections import deque


def fall_and_winter():
    for i in range(N):
        for j in range(N):
            for t in board[i][j][TREE]:
                if t % 5 == 0:
                    for d in range(8):
                        if 0 <= i + dx[d] < N and 0 <= j + dy[d] < N:
                            board[i+dx[d]][j+dy[d]][TREE].appendleft(1)
                            board[i+dx[d]][j+dy[d]][NUM] += 1
            board[i][j][MEAL] += new_meal[i][j]


def summer():
    for i in range(N):
        for j in range(N):
            board[i][j][MEAL] += board[i][j][DEAD]
            board[i][j][DEAD] = 0


def spring():
    for i in range(N):
        for j in range(N):
            for _ in range(board[i][j][NUM]):
                tree_year = board[i][j][TREE].popleft()
                if tree_year <= board[i][j][MEAL]:  # 작거나 같으면 양분 섭취 가능
                    board[i][j][MEAL] -= tree_year  # 나이만큼 양분 빼기
                    board[i][j][TREE].append((tree_year+1))
                else:  # dead
                    board[i][j][DEAD] += tree_year // 2
                    board[i][j][NUM] -= 1


def solve():
    for k in range(K):
        spring()
        summer()
        fall_and_winter()

    ret = 0
    for i in range(N):
        for j in range(N):
            ret += board[i][j][NUM]
    return ret


MEAL, TREE, DEAD, NUM = 0, 1, 2, 3
input = sys.stdin.readline
N, M, K = map(int, input().split())
board = [[[5, [], 0, 0] for _ in range(N)] for _ in range(N)]  # meal, trees(ages), num, dead
new_meal = [list(map(int, input().split())) for _ in range(N)]

dx = [-1, -1, -1, 0, 0, 1, 1, 1]
dy = [-1, 0, 1, -1, 1, -1, 0, 1]

for _ in range(M):
    x, y, z = map(int, input().split())
    board[x-1][y-1][TREE].append(z)  # tree 추가

for i in range(N):
    for j in range(N):
        board[i][j][TREE] = deque(sorted(board[i][j][TREE]))
        board[i][j][NUM] = len(board[i][j][TREE])

print(solve())

 

'알고리즘 > 시뮬레이션' 카테고리의 다른 글

SWEA 2382번. 미생물 격리  (0) 2020.04.24
17144번. 미세먼지 안녕!  (0) 2020.04.21
15685번. 드래곤 커브  (0) 2020.04.16
14891번. 톱니바퀴  (0) 2020.04.13
14503번. 로봇 청소기  (0) 2020.04.13

http://boj.kr/17609 

 

 

 
먼저 is_palindrome 은 회문인지 알아보는 함수이다. str[i] == str[길이-i-1] 인지 검사해서 회문인지 알아낸다. i의 범위는 range(0, 스트링 길이의 절반+1) 이다. 스트링 길이의 절반+1인 이유는 직접 해보면 알겠지만 range (a,b) 는 a부터 b-1까지 리턴하기 때문이다.
회문이 아니라면 이제 한번더 기회를 줘서 유사회문인지 알아봐야 한다.
방법이 두가지가 있는데, 양쪽을 비교했는데 서로 다른 문자를 발견하면 1) 왼쪽 문자를 무시하거나 2) 오른쪽 문자를 무시하는 방법이 있다.
왼쪽 문자를 무시하는 방법은 i -> i+1 이고,
오른쪽 문자를 무시하는 방법은 스트링길이-i-1 -> 스트링길이-i-1-1 이다.
두 방법을 모두 시도해본 후에 그렇게 한 문자를 무시하니 회문이 된다면 유사 회문이고,
그랬는데도 서로다른 문자가 나오면 이것도 저것도 아닌 문자열이다.


import sys


# 왼쪽을 +1 해서 탐색, i는 다른 문자가 나온 위치
def can_palindrome_left(str, i, length): 
    for j in range(i, length):
        if str[j+1] != str[-j-1]:
            return 2
    return 1


# 오른쪽을 -1 해서 탐색, i는 다른 문자가 나온 위치
def can_palindrome_right(str, i, length):  
    for j in range(i, length):
        if str[j] != str[-j-1-1]:
            return 2
    return 1


def is_palindrome(str):
    length = (len(str) // 2) + 1
    for i in range(length):
        if str[i] != str[-i-1]:
            if can_palindrome_left(str, i, length) == 2:
                if can_palindrome_right(str, i, length) == 2:
                    return 2
                else:
                    return 1
            else:
                return 1
    return 0


input = sys.stdin.readline
N = int(input())

for _ in range(N):
    print(is_palindrome(list(input()[:-1])))

'알고리즘 > 브루트포스' 카테고리의 다른 글

16637. 괄호 추가하기 (2)  (0) 2020.05.12
16637번. 괄호 추가하기  (0) 2020.05.11
12100번. 2048 (Easy)  (0) 2020.05.04
12100. 2048 (Easy)  (0) 2020.01.07
2231. 분해합  (0) 2019.11.20

+ Recent posts