├── .DS_Store ├── 2020년 상반기 삼성전자 기출문제 ├── 46_아기 상어★★★★★ │ ├── solution.py │ └── solution2.py ├── 47_청소년 상어★★★★★ │ └── solution.py └── 48_어른 상어 │ └── solution.py ├── README.md ├── 알고리즘 기출문제 ├── BFS&DFS │ ├── 15_특정 거리의 도시 찾기★★★ │ │ └── solution.py │ ├── 16_연구소 │ │ └── solution.py │ ├── 17_경쟁적 전염 │ │ └── solution.py │ ├── 18_괄호 변환 │ │ └── solution.py │ ├── 19_연산자 끼워 넣기★★★★★DFS이용 다시풀어보기 │ │ └── solution.py │ ├── 20_감시 피하기 │ │ └── solution.py │ ├── 21_인구 이동 │ │ └── solution.py │ └── 22_블록 이동하기★★★★★ │ │ └── solution.py ├── DP │ ├── 31_금광 │ │ └── solution.py │ ├── 32_정수 삼각형 │ │ └── solution.py │ ├── 33_퇴사★★★ │ │ └── solution.py │ ├── 34_병사 배치하기 │ │ └── solution.py │ ├── 35_못생긴 수★★★ │ │ └── solution.py │ └── 36_편집 거리★★★★★ │ │ └── solution.py ├── 구현 │ ├── 07_럭키 스트레이트 │ │ └── solution.py │ ├── 08_문자열 재정렬 │ │ └── solution.py │ ├── 09_문자열 압축★★★ │ │ └── solution.py │ ├── 10_자물쇠와 열쇠★★★ │ │ ├── readme.md │ │ └── solution.py │ ├── 11_뱀 │ │ └── solution.py │ ├── 12_기둥과 보 설치★★★★★ │ │ └── solution.py │ └── 13_치킨 배달★★★ │ │ ├── readme.md │ │ └── solution.py ├── 그래프 이론 │ ├── 41_여행 계획 │ │ └── solution.py │ ├── 42_탑승구★★★★★ │ │ └── solution.py │ ├── 43_어두운 길 │ │ └── solution.py │ ├── 44_행성 터널★★★★★ │ │ ├── readme.md │ │ └── solution.py │ └── 45_최종 순위★★★★★ │ │ └── solution.py ├── 그리디 │ ├── 01_모험가 길드★ │ │ └── solution.py │ ├── 02_곱하기 혹은 더하기 │ │ └── solution.py │ ├── 03_문자열 뒤집기★ │ │ └── solution.py │ ├── 04_만들 수 없는 금액★★★★★ │ │ └── solution.py │ ├── 05_볼링봉 고르기 │ │ └── solution.py │ └── 06_무지의 먹방 라이브★★★★★ │ │ └── solution.py ├── 이진 탐색 │ ├── 27_정렬된 배열에서 특정 수의 개수 구하기★★★ │ │ └── solution.py │ └── 28_고정값 찾기★★★★★ │ │ └── solution.py ├── 정렬 │ ├── 23_국영수 │ │ └── solution.py │ ├── 24_안테사 │ │ └── solution.py │ ├── 25_실패율 │ │ └── solution.py │ └── 26_카드 정렬하기 │ │ └── solution.py └── 최단 경로 │ ├── 37_플로이드 │ └── solution.py │ ├── 38_정확한 순위 │ └── solution.py │ ├── 39_화성 탐사 │ └── solution.py │ └── 40_숨바꼭질 │ └── solution.py └── 알고리즘 이론 ├── 111pg_상하좌우 └── solution.py ├── 113pg_시각 └── solution.py ├── 115pg_왕실의 나이트 └── solution.py ├── 118pg_게임 개발 └── solution.py ├── 142pg_DFS └── solution.py ├── 147pg_BFS └── solution.py ├── 149pg_음료수 얼려 먹기 ├── readme.md └── solution.py ├── 152pg_미로 탈출 ├── readme.md └── solution.py ├── 159pg_선택정렬 ├── readme.md └── solution.py ├── 165pg_삽입 정렬 ├── readme.md └── solution.py ├── 168pg_퀵 정렬 ├── readme.md └── solution.py ├── 174pg_계수정렬 ├── readme.md └── solution.py ├── 176pg_파이썬 정렬 ├── readme.md └── solution.py ├── 178pg_위에서 아래로 └── solution.py ├── 180pg_성적이 낮은 순서로 학생 출력하기 └── solution.py ├── 182pg_두 배열의 원소 교체 └── solution.py ├── 187pg_순차탐색 ├── readme.md └── solution.py ├── 188pg_이진탐색 ├── readme.md └── solution.py ├── 197pg_부품찾기 ├── readme.md └── solution.py ├── 201pg_떡볶이 떡 만들기 └── solution.py ├── 214pg_다이나믹 프로그래밍 └── solution.py ├── 217pg_1로 만들기 ├── readme.md └── solution.py ├── 220pg_개미 전사 └── solution.py ├── 223pg_바닥공사 └── solution.py ├── 226pg_효율적인 화폐 구성 └── solution.py ├── 238pg_다익스트라 알고리즘 ├── readme.md └── solution.py ├── 248pg_개선된 다익스트라 알고리즘 ├── readme.md └── solution.py ├── 258pg_플로이드 워셜 알고리즘 ├── readme.md └── solution.py ├── 259pg_미래도시 └── solution.py ├── 262pg_전보 └── solution.py ├── 279pg_서로소 집합을 활용한 union-find 알고리즘 ├── readme.md └── solution.py ├── 280pg_서로소 집합을 활용한 사이클 판별 └── solution.py ├── 281pg_신장트리 └── readme.md ├── 288pg_크루스칼 알고리즘 ├── readme.md └── solution.py ├── 290pg_위상정렬 ├── readme.md └── solution.py ├── 298pg_팀 결성 └── solution.py ├── 300pg_도시 분할 계획 └── solution.py ├── 303pg_커리큘럼 └── solution.py ├── 87pg_거스름돈 └── solution.py ├── 92pg_큰 수의 법칙 └── solution.py ├── 96pg_숫자 카드 게임 └── solution.py └── 99pg_1이 될 때까지 └── solution.py /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiwoong96/python-for-coding-test-ndb796-/574735bbb5d5a16b20c8f72a010e81805cfd6b40/.DS_Store -------------------------------------------------------------------------------- /2020년 상반기 삼성전자 기출문제/46_아기 상어★★★★★/solution.py: -------------------------------------------------------------------------------- 1 | import time 2 | from collections import deque 3 | import sys 4 | input = sys.stdin.readline 5 | 6 | N = int(input()) 7 | board = [] 8 | 9 | 10 | 11 | 12 | for i in range(N): 13 | tmp = list(map(int,input().split())) 14 | board.append(tmp) 15 | for k in range(len(tmp)): 16 | if tmp[k] == 9: 17 | board[i][k] = 0 18 | s_x = i 19 | s_y = k 20 | 21 | dxy = [[0,1],[0,-1],[1,0],[-1,0]] 22 | 23 | def BFS(board,s_x,s_y,s_lv): 24 | visited = [[-1 for _ in range(N)]for _ in range(N)] 25 | q = deque() 26 | q.append((s_x,s_y)) 27 | visited[s_x][s_y] = 0 28 | while q: 29 | now_x, now_y = q.popleft() 30 | 31 | for dt in dxy: 32 | tmp_x,tmp_y = now_x + dt[0] , now_y + dt[1] 33 | if 0<=tmp_x visited[i][j]: 50 | min_val = visited[i][j] 51 | min_x, min_y = i, j 52 | #print("Find", min_x, min_y, min_val) 53 | if min_val != 1e9: 54 | #print("Find") 55 | is_EAT = True 56 | board[min_x][min_y] =0 57 | return board, min_x, min_y,is_EAT 58 | 59 | def solution(board): 60 | s_lv,cnt =2, 0 61 | min_x = s_x 62 | min_y = s_y 63 | result = 0 64 | while True: 65 | #print("입장",min_x,min_y,s_lv) 66 | visited = BFS(board,min_x, min_y, s_lv) 67 | board, min_x, min_y, is_EAT = eat(visited, s_lv) 68 | if is_EAT: 69 | result += visited[min_x][min_y] 70 | cnt += 1 71 | if cnt == s_lv: 72 | cnt = 0 73 | s_lv += 1 74 | else: 75 | break 76 | 77 | return result 78 | 79 | result = solution(board) 80 | print(result) 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /2020년 상반기 삼성전자 기출문제/46_아기 상어★★★★★/solution2.py: -------------------------------------------------------------------------------- 1 | import time 2 | from collections import deque 3 | import sys 4 | input = sys.stdin.readline 5 | 6 | N = int(input()) 7 | 8 | board = [] 9 | s_x,s_y = 0,0 10 | s_lv = 2 11 | for i in range(N): 12 | tmp = list(map(int,input().split())) 13 | for j in range(len(tmp)): 14 | if tmp[j] == 9: 15 | s_x,s_y = i,j 16 | tmp[j] = 0 17 | board.append(tmp) 18 | 19 | def print_board(board): 20 | for data in board: 21 | print(data) 22 | print() 23 | 24 | dx = [0,0,1,-1] 25 | dy = [1,-1,0,0] 26 | 27 | def find(board,s_x,s_y,s_lv): 28 | new_board = [[-1 for _ in range(N)] for _ in range(N)] 29 | q = deque() 30 | q.append((s_x,s_y)) 31 | new_board[s_x][s_y] = 0 32 | 33 | while q: 34 | x,y = q.popleft() 35 | 36 | for i in range(4): 37 | tmp_x,tmp_y = x+dx[i],y+dy[i] 38 | 39 | if 0<=tmp_x new_board[i][j]: 60 | min_val = new_board[i][j] 61 | s_x,s_y = i,j 62 | is_Find = True 63 | 64 | 65 | if is_Find: 66 | result += new_board[s_x][s_y] 67 | board[s_x][s_y] = 0 68 | count += 1 69 | if count == s_lv: 70 | s_lv +=1 71 | count = 0 72 | else: 73 | break 74 | 75 | return result 76 | 77 | 78 | 79 | 80 | result = solution(board,s_x,s_y,s_lv) 81 | 82 | print(result) -------------------------------------------------------------------------------- /2020년 상반기 삼성전자 기출문제/47_청소년 상어★★★★★/solution.py: -------------------------------------------------------------------------------- 1 | 2 | import copy 3 | 4 | from collections import deque 5 | import sys 6 | input = sys.stdin.readline 7 | 8 | dx = [0,-1,-1,0,1,1,1,0,-1] 9 | dy = [0,0,-1,-1,-1,0,1,1,1] 10 | 11 | board = [] 12 | 13 | for i in range(4): 14 | tmp = list(map(int,input().split())) 15 | board.append([[tmp[0],tmp[1]],[tmp[2],tmp[3]],[tmp[4],tmp[5]],[tmp[6],tmp[7]]]) 16 | 17 | def find_fish(board,idx): 18 | x,y,dir = 0,0,-1 19 | for i in range(4): 20 | for j in range(4): 21 | if board[i][j][0] == idx: 22 | x = i 23 | y = j 24 | dir = board[i][j][1] 25 | break 26 | return x,y,dir 27 | 28 | def fish_move(board): 29 | for idx in range(1,17): 30 | x,y,dir = find_fish(board,idx) 31 | 32 | ##해당 숫자가 없는 경우 33 | if dir == -1: 34 | continue 35 | 36 | tmp_dir = dir 37 | while True: 38 | 39 | tmp_x = x+dx[tmp_dir] 40 | tmp_y = y+dy[tmp_dir] 41 | 42 | if 0<=tmp_x<4 and 0<=tmp_y <4: 43 | if board[tmp_x][tmp_y][0] != -1: 44 | board[tmp_x][tmp_y] , board[x][y] = board[x][y] ,board[tmp_x][tmp_y] 45 | board[tmp_x][tmp_y][1] = tmp_dir 46 | break 47 | 48 | tmp_dir += 1 49 | if tmp_dir== 9: tmp_dir = 1 50 | if tmp_dir == dir: 51 | break 52 | 53 | return board 54 | 55 | def solution(board): 56 | q = deque() 57 | result = 0 58 | s_x, s_y = 0,0 59 | s_dir = board[s_x][s_y][1] 60 | result += board[s_x][s_y][0] 61 | board[s_x][s_y][0] = -1 62 | q.append((board,result)) 63 | max_value = -1 64 | 65 | while q: 66 | now_board, now_result= q.popleft() 67 | idx = 0 68 | 69 | if max_value < now_result: max_value = now_result 70 | 71 | #상어 찾기 72 | s_x,s_y,s_dir = find_fish(now_board,-1) 73 | 74 | now_board = fish_move(now_board) 75 | 76 | 77 | 78 | while True: 79 | idx += 1 80 | tmp_s_x, tmp_s_y = s_x+dx[s_dir]*idx, s_y+dy[s_dir]*idx 81 | tmp_board = copy.deepcopy(now_board) 82 | tmp_result = now_result 83 | if 0<=tmp_s_x<4 and 0<=tmp_s_y<4: 84 | if tmp_board[tmp_s_x][tmp_s_y][0] != 0: #and tmp_board[tmp_s_x][tmp_s_y][0] != -1: 85 | tmp_board[s_x][s_y][0] = 0 86 | tmp_board[s_x][s_y][1] = 0 87 | 88 | tmp_result += tmp_board[tmp_s_x][tmp_s_y][0] 89 | tmp_board[tmp_s_x][tmp_s_y][0] = -1 90 | q.append((tmp_board,tmp_result)) 91 | else: 92 | break 93 | return max_value 94 | 95 | result = solution(board) 96 | print(result) 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /2020년 상반기 삼성전자 기출문제/48_어른 상어/solution.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | import sys 3 | input = sys.stdin.readline 4 | 5 | N,M,K = map(int,input().split()) 6 | 7 | board = [[[]for _ in range(N)] for _ in range(N)] 8 | 9 | 10 | dx = [0,-1,1,0,0] 11 | dy = [0,0,0,-1,1] 12 | 13 | for i in range(N): 14 | tmp = list(map(int,input().split())) 15 | for j in range(len(tmp)): 16 | if tmp[j] !=0: 17 | board[i][j].append(True) 18 | board[i][j].append(tmp[j]) 19 | board[i][j].append(K) 20 | board[i][j].append(0) ##상어의 존재유무, 상어의 번호,간 냄새의 남은 시간, 방향 21 | else: 22 | board[i][j].append(False) 23 | board[i][j].append(0) 24 | board[i][j].append(0) 25 | board[i][j].append(0) 26 | 27 | def find_shark(board,idx): 28 | x,y,dir = 0,0,-1 29 | for i in range(N): 30 | for j in range(N): 31 | if board[i][j][0] == True and board[i][j][1] == idx: 32 | x = i 33 | y = j 34 | dir = board[i][j][3] 35 | 36 | return x,y,dir 37 | 38 | 39 | tmp = list(map(int,input().split())) 40 | for idx in range(len(tmp)): 41 | x,y,dir = find_shark(board,idx+1) 42 | board[x][y][3] = tmp[idx] 43 | shark_dir = [[]for _ in range(M+1)] 44 | 45 | for i in range(1,M+1): 46 | for j in range(4): 47 | tmp = list(map(int,input().split())) 48 | shark_dir[i].append(tmp) 49 | 50 | 51 | def print_board(board): 52 | for i in board: 53 | print(i) 54 | print() 55 | 56 | """ 57 | for i in shark_dir: 58 | print(i) 59 | print() 60 | """ 61 | def move_shark(board): 62 | q = deque() 63 | for idx in range(1,M+1): 64 | is_move = False 65 | x,y,dir = find_shark(board,idx) 66 | if dir == -1: 67 | continue 68 | for i in range(4): 69 | tmp_dir = shark_dir[idx][dir-1][i] 70 | tmp_x = x + dx[tmp_dir] 71 | tmp_y = y + dy[tmp_dir] 72 | if 0<=tmp_x result: 54 | min_val = result 55 | 56 | for nvx, nvy in v: 57 | board[nvx][nvy] = 0 58 | 59 | print(len(no_virus)-3-min_val) 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /알고리즘 기출문제/BFS&DFS/17_경쟁적 전염/solution.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | import sys 3 | input = sys.stdin.readline 4 | 5 | N, K = map(int,input().split()) 6 | 7 | board = [] 8 | virus = [[]for _ in range(K+1)] 9 | 10 | for i in range(N): 11 | tmp = list(map(int,input().split())) 12 | board.append(tmp) 13 | for j in range(len(tmp)): 14 | if tmp[j] != 0: 15 | virus[tmp[j]].append((i,j)) 16 | 17 | 18 | S,X,Y = map(int,input().split()) 19 | 20 | dxy = [[0,1],[0,-1],[1,0],[-1,0]] 21 | 22 | def BFS(virus): 23 | q = deque() 24 | for v in range(len(virus)): 25 | for vx,vy in virus[v]: 26 | q.append((0,v,vx,vy)) 27 | 28 | while q: 29 | time,idx, x,y = q.popleft() 30 | """ 31 | for boards in board: 32 | print(boards) 33 | print() 34 | """ 35 | if time >=S: 36 | break 37 | 38 | for dt in dxy: 39 | tmp_x,tmp_y = x+ dt[0], y+dt[1] 40 | if 0<= tmp_x max_val: 44 | max_val = result 45 | return min_val, max_val 46 | 47 | min_val, max_val = solution(operand,operator) 48 | 49 | 50 | print(max_val) 51 | print(min_val) -------------------------------------------------------------------------------- /알고리즘 기출문제/BFS&DFS/20_감시 피하기/solution.py: -------------------------------------------------------------------------------- 1 | import copy 2 | from collections import deque 3 | from itertools import combinations 4 | import sys 5 | input = sys.stdin.readline 6 | 7 | N = int(input()) 8 | board = [] 9 | teacher = [] 10 | nobody = [] 11 | for i in range(N): 12 | tmp = list(input().split()) 13 | board.append(tmp) 14 | for s in range(len(tmp)): 15 | if tmp[s] == 'T': 16 | teacher.append((i,s)) 17 | elif tmp[s] == 'X': 18 | nobody.append((i,s)) 19 | 20 | dxy = [[0,1],[0,-1],[1,0],[-1,0]] 21 | 22 | def check(teacher,board): 23 | q = deque() 24 | for tx,ty in teacher: 25 | for i in range(len(dxy)): 26 | tmp_x, tmp_y = tx + dxy[i][0], ty + dxy[i][1] 27 | if 0 <= tmp_x < N and 0 <= tmp_y < N : 28 | if board[tmp_x][tmp_y] == 'X': 29 | q.append((i, tmp_x, tmp_y)) 30 | elif board[tmp_x][tmp_y] == 'S': 31 | return False 32 | 33 | while q: 34 | 35 | dir,x,y = q.popleft() 36 | tmp_x, tmp_y = x+dxy[dir][0], y+dxy[dir][1] 37 | if 0<= tmp_x< N and 0<=tmp_y세로 8 | def rotate_1(board,x1,y1,x2,y2): 9 | N = len(board) 10 | result = [] 11 | for dt in dx: 12 | tmp_x1,tmp_x2 = x1+dt, x2+dt 13 | if 0<=tmp_x1가로 19 | def rotate_2(board,x1,y1,x2,y2): 20 | N = len(board) 21 | result = [] 22 | for dt in dy: 23 | tmp_y1,tmp_y2 = y1+dt,y2+dt 24 | if 0<=tmp_y1 result: 41 | min_value = result 42 | 43 | 44 | return min_value 45 | 46 | 47 | result= solution(s) 48 | print(result) 49 | -------------------------------------------------------------------------------- /알고리즘 기출문제/구현/10_자물쇠와 열쇠★★★/readme.md: -------------------------------------------------------------------------------- 1 | 키는 자물쇠보다 항상 작으므로 자물쇠의 크기를 3배늘려 가운데에 배치한 뒤 2 | 새로운 자물쇠와 키를 비교하면 더 수월하게 진행할 수 있다. 3 | -------------------------------------------------------------------------------- /알고리즘 기출문제/구현/10_자물쇠와 열쇠★★★/solution.py: -------------------------------------------------------------------------------- 1 | 2 | \ 3 | def rotate(key): 4 | N = len(key) 5 | new_key = [[0 for _ in range(N)]for _ in range(N)] 6 | for i in range(N): 7 | for j in range(N): 8 | new_key[i][j] = key[N-j-1][i] 9 | return new_key 10 | 11 | 12 | def check(new_lock): 13 | N = len(new_lock)//3 14 | for i in range(N,2*N): 15 | for j in range(N,2*N): 16 | if new_lock[i][j] != 1: 17 | return False 18 | 19 | return True 20 | 21 | def solution(key,lock): 22 | N = len(lock) 23 | M = len(key) 24 | 25 | new_lock = [[0 for _ in range(3 * N)] for _ in range(3 * N)] 26 | for i in range(N): 27 | for j in range(N): 28 | new_lock[N + i][N + j] = lock[i][j] 29 | 30 | result = False 31 | 32 | for k in range(4): 33 | key = rotate(key) 34 | for h in range(2*N): 35 | for w in range(2*N): 36 | for i in range(M): 37 | for j in range(M): 38 | new_lock[i+h][j+w] += key[i][j] 39 | 40 | if check(new_lock) == True: 41 | return True 42 | for i in range(M): 43 | for j in range(M): 44 | new_lock[i+h][j+w] -= key[i][j] 45 | 46 | 47 | return False 48 | 49 | key = [[1,0,0,0], 50 | [0,0,1,0], 51 | [0,1,1,1], 52 | [1,1,1,1]] 53 | 54 | lock = [[1,1,1], 55 | [1,1,0], 56 | [1,0,1]] 57 | 58 | print(solution(key,lock)) 59 | -------------------------------------------------------------------------------- /알고리즘 기출문제/구현/11_뱀/solution.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | import sys 4 | 5 | input = sys.stdin.readline 6 | 7 | 8 | def solution(board, direction): 9 | dxy = [[0, 1], [1, 0], [0, -1], [-1, 0]] 10 | queue = deque() 11 | dir = 0 12 | x, y = 0, 0 13 | queue.append((x,y)) 14 | board[x][y] = 2 15 | time = 1 16 | 17 | # 오른쪽으로 이동하면 dir +1 3에서 오른쪽이면 0으로 초기화 18 | # 왼쪽으로 이동하면 dir -1 0에서 왼쪽이면 3으로 초기화 19 | # 0 : 비어있는 공간 20 | # 1 : 사과가 있는 공간 21 | # 2 : 뱀의 몸통이 있는 공간 22 | 23 | while True: 24 | tmp_x, tmp_y = x + dxy[dir][0], y + dxy[dir][1] 25 | if tmp_x < 0 or tmp_y < 0 or tmp_x >= N or tmp_y >= N or board[tmp_x][tmp_y] == 2: 26 | break 27 | 28 | x,y = tmp_x,tmp_y 29 | if board[x][y] == 1: 30 | board[x][y] = 2 31 | queue.append((x,y)) 32 | 33 | elif board[x][y] == 0: 34 | board[x][y] = 2 35 | tmp = queue.popleft() 36 | before_x, before_y = tmp[0],tmp[1] 37 | board[before_x][before_y] = 0 38 | queue.append((x,y)) 39 | 40 | if direction and direction[0][0] == time: 41 | change = direction.popleft()[1] 42 | #방향이 오른쪽 43 | if change == 'D': 44 | if dir == 3: 45 | dir = 0 46 | else: 47 | dir += 1 48 | else: 49 | if dir == 0: 50 | dir = 3 51 | else: 52 | dir -= 1 53 | 54 | time += 1 55 | 56 | 57 | return time 58 | 59 | 60 | N = int(input()) 61 | K = int(input()) 62 | 63 | board = [[0 for _ in range(N)] for _ in range(N)] 64 | for _ in range(K): 65 | x, y = map(int, input().split()) 66 | board[x - 1][y - 1] = 1 67 | 68 | direction = deque() 69 | 70 | L = int(input()) 71 | for _ in range(L): 72 | a, b = list(input().split()) 73 | direction.append((int(a), b)) 74 | 75 | time = solution(board,direction) 76 | print(time) -------------------------------------------------------------------------------- /알고리즘 기출문제/구현/12_기둥과 보 설치★★★★★/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | 4 | 5 | def solution(n, build_frame): 6 | # 0 : 설치X 7 | # 1 : 기둥 8 | # 2 : 보 9 | board = [[False for _ in range(2*n)] for _ in range(2*n)] 10 | 11 | for i in range(len(build_frame)): 12 | y,x,a,b = build_frame[i] 13 | 14 | 15 | answer = [[]] 16 | 17 | 18 | return answer -------------------------------------------------------------------------------- /알고리즘 기출문제/구현/13_치킨 배달★★★/readme.md: -------------------------------------------------------------------------------- 1 | [Tip] 2 | 조합을 통해 구하는 방식 3 | 따로 리스트를 만들어서 조합을 만들기 보단 치킨집들만 모은 리스트 자체를 조합을 넣는데 4 | from itertools import combinations 5 | 6 | combination = list(combinations(chicken_list(표본),개수)) 7 | -------------------------------------------------------------------------------- /알고리즘 기출문제/구현/13_치킨 배달★★★/solution.py: -------------------------------------------------------------------------------- 1 | from itertools import combinations 2 | import sys 3 | input = sys.stdin.readline 4 | INF = int(1e9) 5 | 6 | N,M = map(int,input().split()) 7 | 8 | board = [] 9 | house = [] 10 | chicken_shop = [] 11 | 12 | for i in range(N): 13 | data = list(map(int,input().split())) 14 | for k in range(len(data)): 15 | if data[k] == 1: 16 | house.append((i,k)) 17 | elif data[k] == 2: 18 | chicken_shop.append((i,k)) 19 | 20 | candidates = list(combinations(chicken_shop,M)) 21 | 22 | 23 | def solution(candidates): 24 | result = INF 25 | 26 | for candidate in candidates: 27 | tmp = [INF for _ in range(len(house))] 28 | for cx,cy in candidate: 29 | for k in range(len(house)): 30 | hx,hy = house[k][0],house[k][1] 31 | tmp[k] = min(tmp[k], abs(hx - cx) + abs(hy - cy)) 32 | if sum(tmp) < result: 33 | result = sum(tmp) 34 | return result 35 | 36 | result = solution(candidates) 37 | print(result) 38 | 39 | 40 | #0 : 빈칸 41 | #1 : 집 42 | #2 : 치킨집 43 | 44 | 45 | -------------------------------------------------------------------------------- /알고리즘 기출문제/그래프 이론/41_여행 계획/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | INF = int(1e9) 4 | N, M = map(int,input().split()) 5 | 6 | graph = [] 7 | for _ in range(N): 8 | graph.append(list(map(int,input().split()))) 9 | 10 | 11 | to_visit = list(map(int,input().split())) 12 | parent = [i for i in range(N+1)] 13 | 14 | def find_parent(x): 15 | if parent[x] != x: 16 | parent[x] = find_parent(parent[x]) 17 | return parent[x] 18 | 19 | def union(a,b): 20 | a = find_parent(a) 21 | b = find_parent(b) 22 | if a O(NlogN)으로 단축 가능. -------------------------------------------------------------------------------- /알고리즘 기출문제/그래프 이론/44_행성 터널★★★★★/solution.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | import sys 3 | input = sys.stdin.readline 4 | 5 | N = int(input()) 6 | 7 | 8 | 9 | Edge = [] 10 | x = [] 11 | y = [] 12 | z = [] 13 | 14 | for i in range(N): 15 | a,b,c = map(int,input().split()) 16 | x.append((a,i)) 17 | y.append((b,i)) 18 | z.append((c,i)) 19 | 20 | x.sort() 21 | y.sort() 22 | z.sort() 23 | 24 | for i in range(N-1): 25 | heapq.heappush(Edge,(abs(x[i][0]-x[i+1][0]),x[i][1],x[i+1][1])) 26 | heapq.heappush(Edge,(abs(y[i][0] - y[i + 1][0]),y[i][1],y[i+1][1])) 27 | heapq.heappush(Edge,(abs(z[i][0] - z[i + 1][0]),z[i][1],z[i+1][1])) 28 | 29 | 30 | 31 | 32 | 33 | def find_parent(parent,x): 34 | if parent[x] != x: 35 | parent[x] = find_parent(parent,parent[x]) 36 | return parent[x] 37 | 38 | def union(parent,a,b): 39 | a = find_parent(parent,a) 40 | b = find_parent(parent,b) 41 | if a= i: 15 | result += 1 16 | count = 0 17 | 18 | print(result) 19 | 20 | 21 | -------------------------------------------------------------------------------- /알고리즘 기출문제/그리디/02_곱하기 혹은 더하기/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | 4 | data= input().strip('\n') 5 | 6 | result = int(data[0]) 7 | 8 | for i in range(1,len(data)): 9 | now = int(data[i]) 10 | if result==0 or result==1 or now ==0 or now==1: 11 | result += now 12 | else: 13 | result *= now 14 | 15 | print(result) 16 | 17 | 18 | -------------------------------------------------------------------------------- /알고리즘 기출문제/그리디/03_문자열 뒤집기★/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | 4 | data = input() 5 | 6 | result = [0,0] 7 | before = data[0] 8 | 9 | for i in range(1,len(data)): 10 | if data[i] == before: 11 | continue 12 | else: 13 | result[int(before)] += 1 14 | before = data[i] 15 | 16 | print(result) -------------------------------------------------------------------------------- /알고리즘 기출문제/그리디/04_만들 수 없는 금액★★★★★/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | 4 | N = int(input()) 5 | 6 | data = list(map(int,input().split())) 7 | 8 | data.sort() 9 | 10 | target = 1 11 | 12 | for i in data: 13 | if target < i: 14 | break 15 | target += i 16 | 17 | print(target) -------------------------------------------------------------------------------- /알고리즘 기출문제/그리디/05_볼링봉 고르기/solution.py: -------------------------------------------------------------------------------- 1 | """import sys 2 | input = sys.stdin.readline 3 | 4 | N, M = map(int,input().split()) 5 | data = list(map(int,input().split())) 6 | 7 | data.sort() 8 | 9 | tmp = 1 10 | before = 0 11 | sumation = 0 12 | 13 | for i in data: 14 | if before == i: 15 | tmp += 1 16 | else: 17 | if tmp >= 2: 18 | sumation += tmp * (tmp - 1) // 2 19 | tmp = 1 20 | before = i 21 | if data[-1] == i: 22 | if tmp >= 2: 23 | sumation += tmp * (tmp - 1) // 2 24 | 25 | result = N*(N-1)//2 - sumation 26 | 27 | print(result)""" 28 | 29 | import sys 30 | input = sys.stdin.readline 31 | 32 | N,M = map(int,input().split()) 33 | 34 | data =list(map(int,input().split())) 35 | 36 | Ball = [0 for _ in range(N+1)] 37 | 38 | for i in data: 39 | Ball[i] += 1 40 | 41 | result = 0 42 | 43 | for i in range(1,N+1): 44 | N -= Ball[i] 45 | result += Ball[i]*N 46 | 47 | print(result) -------------------------------------------------------------------------------- /알고리즘 기출문제/그리디/06_무지의 먹방 라이브★★★★★/solution.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | def solution(food_items, k): 4 | if sum(food_items) <= k: 5 | return -1 6 | 7 | q = [] 8 | 9 | for i in range(len(food_items)): 10 | heapq.heappush(q,(food_items[i],i+1)) 11 | 12 | before = 0 13 | sum_value = 0 14 | length = len(q) 15 | 16 | while sum_value + (q[0][0] - before) * length < k: 17 | now = heapq.heappop(q)[0] 18 | sum_value += (now - before) * length 19 | length -= 1 20 | before = now 21 | 22 | q.sort(key = lambda x:x[1]) 23 | result = q[(k-sum_value)%length][1] 24 | return result 25 | 26 | food_items = [3,1,2] 27 | k = 5 28 | result = solution(food_items,k) 29 | 30 | print(result) 31 | 32 | -------------------------------------------------------------------------------- /알고리즘 기출문제/이진 탐색/27_정렬된 배열에서 특정 수의 개수 구하기★★★/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | import sys 3 | input = sys.stdin.readline 4 | 5 | N, x = map(int,input().split()) 6 | 7 | data = list(map(int,input().split())) 8 | 9 | 10 | while len(data) > 1: 11 | result = 0 12 | if data[len(data)//2] == x: 13 | for i in data: 14 | if i == 2: 15 | result += 1 16 | break 17 | elif data[len(data)//2] > x: 18 | data = data[:(len(data)-1)//2] 19 | else: 20 | data = data[len(data)//2:] 21 | print(data) 22 | if result == 0: 23 | print(-1) 24 | else: 25 | print(result) 26 | """ 27 | 28 | from bisect import bisect_left,bisect_right 29 | import sys 30 | input = sys.stdin.readline 31 | 32 | N, x = map(int,input().split()) 33 | 34 | data = list(map(int,input().split())) 35 | 36 | start = bisect_left(data,x) 37 | end = bisect_right(data,x) 38 | 39 | 40 | if end-start == 0: 41 | print(-1) 42 | else: 43 | print(end-start) -------------------------------------------------------------------------------- /알고리즘 기출문제/이진 탐색/28_고정값 찾기★★★★★/solution.py: -------------------------------------------------------------------------------- 1 | from bisect import bisect_right, bisect_left 2 | import sys 3 | input = sys.stdin.readline 4 | 5 | 6 | N = int(input()) 7 | data = list(map(int,input().split())) 8 | 9 | result = -1 10 | 11 | length = len(data) 12 | find_idx = length//2 13 | find_value 14 | tmp = 0 15 | while data: 16 | if find_idx == data[find_idx]: 17 | result = find_idx 18 | break 19 | elif find_idx > data[find_idx]: 20 | data = data[find_idx:] 21 | 22 | elif find_idx < data[find_idx]: 23 | data = data[:find_idx] 24 | -------------------------------------------------------------------------------- /알고리즘 기출문제/정렬/23_국영수/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | 4 | N = int(input()) 5 | data = [] 6 | for i in range(N): 7 | tmp = list(input().split()) 8 | data.append((tmp[0],int(tmp[1]),int(tmp[2]),int(tmp[3]))) 9 | 10 | data.sort(key = lambda x:(-x[1],x[2],-x[3],x[0])) 11 | 12 | for i in data: 13 | print(i[0]) 14 | -------------------------------------------------------------------------------- /알고리즘 기출문제/정렬/24_안테사/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | 4 | N = int(input()) 5 | 6 | data = list(map(int,input().split())) 7 | 8 | data.sort() 9 | print(data[(len(data)-1)//2]) -------------------------------------------------------------------------------- /알고리즘 기출문제/정렬/25_실패율/solution.py: -------------------------------------------------------------------------------- 1 | N = 4 2 | stages = [4,4,4,4,4] 3 | 4 | def solution(N,stages): 5 | stage = [0 for _ in range(N+2)] 6 | for data in stages: 7 | stage[data] += 1 8 | result = [] 9 | 10 | length = len(stages) 11 | 12 | 13 | for i in range(1,N+1): 14 | if length == 0: 15 | result.append((i,0)) 16 | continue 17 | result.append((i,stage[i]/length)) 18 | length -= stage[i] 19 | 20 | result.sort(key= lambda x:(-x[1],x[0])) 21 | answer = [] 22 | for k in result: 23 | answer.append(k[0]) 24 | return answer 25 | 26 | result = solution(N,stages) 27 | 28 | print(result) 29 | 30 | -------------------------------------------------------------------------------- /알고리즘 기출문제/정렬/26_카드 정렬하기/solution.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | import sys 3 | input = sys.stdin.readline 4 | 5 | N = int(input()) 6 | data = [] 7 | 8 | for i in range(N): 9 | heapq.heappush(data,int(input())) 10 | 11 | 12 | 13 | 14 | def solution(data): 15 | answer = 0 16 | while len(data)>=2: 17 | A = heapq.heappop(data) 18 | B = heapq.heappop(data) 19 | C = A+B 20 | answer += C 21 | heapq.heappush(data,C) 22 | 23 | return answer 24 | 25 | answer = solution(data) 26 | print(answer) 27 | 28 | 29 | -------------------------------------------------------------------------------- /알고리즘 기출문제/최단 경로/37_플로이드/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | INF = int(1e9) 4 | 5 | N = int(input()) 6 | M = int(input()) 7 | graph = [[INF for _ in range(N+1)] for _ in range(N+1)] 8 | 9 | for i in range(M): 10 | start,end,distance = map(int,input().split()) 11 | graph[start][end] = min(graph[start][end],distance) 12 | 13 | def solution(graph): 14 | for k in range(1,N+1): 15 | for i in range(1,N+1): 16 | for j in range(1,N+1): 17 | if i == j: 18 | graph[i][j] = 0 19 | else: 20 | graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j]) 21 | 22 | 23 | return graph 24 | 25 | graph = solution(graph) 26 | for i in range(1,N+1): 27 | for j in range(1,N+1): 28 | if graph[i][j] != INF: 29 | print(graph[i][j], end = ' ') 30 | else: 31 | print(0, end= ' ') 32 | print() 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /알고리즘 기출문제/최단 경로/38_정확한 순위/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | INF = int(1e9) 4 | 5 | N, M = map(int,input().split()) 6 | 7 | graph = [[INF for _ in range(N+1)]for _ in range(N+1)] 8 | 9 | for i in range(M): 10 | start, end = map(int,input().split()) 11 | graph[start][end] = 1 12 | 13 | for k in range(1,N+1): 14 | for i in range(1,N+1): 15 | for j in range(1,N+1): 16 | if i == j: graph[i][j] = 0 17 | else: 18 | if graph[i][j] > graph[i][k] + graph[k][j]: 19 | graph[i][j] = graph[i][k] + graph[k][j] 20 | 21 | 22 | answer = 0 23 | for i in range(1,N+1): 24 | now = i 25 | result = 0 26 | for j in range(1,N+1): 27 | if graph[now][j] == INF and graph[j][now] == INF: 28 | break 29 | else: 30 | result +=1 31 | 32 | if result == N: 33 | answer += 1 34 | 35 | print(answer) -------------------------------------------------------------------------------- /알고리즘 기출문제/최단 경로/39_화성 탐사/solution.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | import sys 3 | input = sys.stdin.readline 4 | INF = int(1e9) 5 | T = int(input()) 6 | 7 | dxy = [[-1,0],[1,0],[0,1],[0,-1]] 8 | 9 | for _ in range(T): 10 | N = int(input()) 11 | 12 | board = [] 13 | for _ in range(N): 14 | board.append(list(map(int,input().split()))) 15 | 16 | distance = [[INF for _ in range(N)] for _ in range(N)] 17 | distance[0][0] = board[0][0] 18 | 19 | q = [] 20 | heapq.heappush(q,(board[0][0],0,0)) 21 | 22 | while q: 23 | dist, x, y = heapq.heappop(q) 24 | 25 | 26 | if distance[x][y] < dist: 27 | continue 28 | 29 | for dt in dxy: 30 | tmp_x, tmp_y = x+dt[0], y+dt[1] 31 | if 0<=tmp_x dist+board[tmp_x][tmp_y]: 33 | distance[tmp_x][tmp_y] = dist + board[tmp_x][tmp_y] 34 | heapq.heappush(q,(distance[tmp_x][tmp_y],tmp_x,tmp_y)) 35 | print(distance[N - 1][N - 1]) 36 | 37 | 38 | """ 39 | 3 40 | 3 41 | 5 5 4 42 | 3 9 1 43 | 3 2 7 44 | 5 45 | 3 7 2 0 1 46 | 2 8 0 9 1 47 | 1 2 1 8 1 48 | 9 8 9 2 0 49 | 3 6 5 1 5 50 | 7 51 | 9 0 5 1 1 5 3 52 | 4 1 2 1 6 5 3 53 | 0 7 6 1 6 8 5 54 | 1 1 7 8 3 2 3 55 | 9 4 0 7 6 4 1 56 | 5 8 3 2 4 8 3 57 | 7 4 8 4 8 3 4 58 | """ 59 | 60 | -------------------------------------------------------------------------------- /알고리즘 기출문제/최단 경로/40_숨바꼭질/solution.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | import sys 3 | input = sys.stdin.readline 4 | INF = int(1e9) 5 | N, M = map(int,input().split()) 6 | 7 | graph = [[] for _ in range(N+1)] 8 | 9 | for i in range(M): 10 | start, end = map(int,input().split()) 11 | graph[start].append(end) 12 | graph[end].append(start) 13 | 14 | def solution(graph): 15 | distance = [INF for _ in range(N+1)] 16 | q = [] 17 | heapq.heappush(q,(0,1))#dist, start 18 | distance[1] = 0 19 | 20 | while q: 21 | dist, now = heapq.heappop(q) 22 | 23 | if distance[now] < dist: 24 | continue 25 | 26 | for new in graph[now]: 27 | if distance[new] > dist + 1 : 28 | distance[new] = dist + 1 29 | q.append((dist+1 , new)) 30 | 31 | return distance 32 | 33 | distance = solution(graph) 34 | 35 | print(distance.index(max(distance[1:])),max(distance[1:]),distance.count(max(distance[1:]))) 36 | -------------------------------------------------------------------------------- /알고리즘 이론/111pg_상하좌우/solution.py: -------------------------------------------------------------------------------- 1 | N = int(input()) 2 | data = list(input().split()) 3 | print(N) 4 | x = 1 5 | y = 1 6 | for i in data: 7 | if i=="R": 8 | if y>=N: 9 | pass 10 | else: 11 | y +=1 12 | if i=="U": 13 | if x<=1: 14 | pass 15 | else: 16 | x -=1 17 | if i=="D": 18 | if x>=N: 19 | pass 20 | else: 21 | x +=1 22 | if i=="L": 23 | if y<=1: 24 | pass 25 | else: 26 | y -=1 27 | 28 | print(x,y) 29 | 30 | """ 31 | N = int(input()) 32 | data = list(input().split()) 33 | x,y = 1,1 34 | 35 | dx = [0,0,-1,1] 36 | dy = [-1,1,0,0] 37 | dir = ['L','R','U','D'] 38 | 39 | for i in data: 40 | nx,ny = 0, 0 41 | for j in range(len(dir)): 42 | if i == dir[j]: 43 | nx = x + dx[j] 44 | ny = y + dy[j] 45 | break 46 | 47 | if nx > N or nx < 1 or ny > N or ny < 1: 48 | continue 49 | else: 50 | x,y = nx,ny 51 | 52 | print(x,y) 53 | """ -------------------------------------------------------------------------------- /알고리즘 이론/113pg_시각/solution.py: -------------------------------------------------------------------------------- 1 | N = int(input()) 2 | 3 | count = 0 4 | 5 | for H in range(N+1): 6 | for M in range(0,60): 7 | for S in range(0,60): 8 | time = str(H) + str(M) + str(S) 9 | if "3" in time: 10 | count += 1 11 | 12 | print(count) 13 | -------------------------------------------------------------------------------- /알고리즘 이론/115pg_왕실의 나이트/solution.py: -------------------------------------------------------------------------------- 1 | start = input() 2 | 3 | dx = [1,-1,1,-1,2,2,-2,-2] 4 | dy = [2,2,-2,-2,1,-1,1,-1] 5 | 6 | x = ord(start[0])-96 7 | y = int(start[1]) 8 | 9 | tmp_x = 0 10 | tmp_y = 0 11 | count = 0 12 | 13 | for i in range(8): 14 | tmp_x = x + dx[i] 15 | tmp_y = y + dy[i] 16 | if tmp_x <= 8 and tmp_x >=1 and tmp_y <=8 and tmp_y >= 1: 17 | #print(tmp_x,tmp_y,i) 18 | count +=1 19 | 20 | print(count) -------------------------------------------------------------------------------- /알고리즘 이론/118pg_게임 개발/solution.py: -------------------------------------------------------------------------------- 1 | N, M = map(int, input().split()) 2 | A, B, d = map(int, input().split()) 3 | 4 | Map = [] 5 | visited = [[0] * M for _ in range(N)] 6 | 7 | for i in range(N): 8 | tmp = list(map(int, input().split())) 9 | Map.append(tmp) 10 | 11 | print("input end") 12 | 13 | 14 | def changeDir(): 15 | global d 16 | if d == 0: 17 | d = 3 18 | else: 19 | d -= 1 20 | print("방향 전환", d) 21 | 22 | 23 | dx = [-1, 0, 1, 0] 24 | dy = [0, 1, 0, -1] 25 | 26 | tmp_x = 0 27 | tmp_y = 0 28 | 29 | count = 0 30 | result = 1 31 | visited[A][B] = 1 32 | while (True): 33 | # 1.방향 전환 34 | changeDir() 35 | tmp_x = A + dx[d] 36 | tmp_y = B + dy[d] 37 | print('tmp_x : {}, tmp_y : {}'.format(tmp_x, tmp_y)) 38 | if tmp_x < 0 or tmp_y < 0 or tmp_x >= M or tmp_y >= N or Map[tmp_x][tmp_y] == 1 or visited[tmp_x][tmp_y] == 1: 39 | count += 1 40 | print("해당방향이 바다이거나 이미 방문한 곳") 41 | if count == 4: 42 | tmp_x = A - dx[d] 43 | tmp_y = B - dy[d] 44 | print("네방향 모두 방문되거나 바다", A, B) 45 | if Map[tmp_x][tmp_y] == 1 or visited[tmp_x][tmp_y] == 1: 46 | print("게임종료") 47 | break 48 | else: 49 | A = tmp_x 50 | B = tmp_y 51 | print("한칸뒤로이동", A, B) 52 | else: 53 | A = tmp_x 54 | B = tmp_y 55 | count = 0 56 | result += 1 57 | visited[A][B] = 1 58 | print("한칸 전진", A, B, d) 59 | DD = int(input()) 60 | 61 | print(result) -------------------------------------------------------------------------------- /알고리즘 이론/142pg_DFS/solution.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | graph = [[], [2, 3, 8], 4 | [1, 7], 5 | [1, 4, 5], 6 | [3, 5], 7 | [3, 4], 8 | [7], 9 | [2, 6], 10 | [1, 7]] 11 | 12 | visited = [False] * 9 13 | 14 | 15 | def DFS(graph, n, visited): 16 | visited[n] = True 17 | print('{}번 노드 방문'.format(n)) 18 | for i in graph[n]: 19 | if not visited[i]: 20 | DFS(graph, i, visited) 21 | 22 | 23 | DFS(graph, 1, visited) 24 | 25 | for i in range(len(visited)): 26 | visited[i] = False 27 | 28 | 29 | 30 | 31 | queue = deque() 32 | queue.append(1) 33 | visited[1] = True 34 | def BFS(graph,visited): 35 | 36 | if not queue: 37 | return 38 | v = queue.popleft() 39 | print('{}번째 노드 방문'.format(v)) 40 | 41 | for i in graph[v]: 42 | if not visited[i]: 43 | queue.append(i) 44 | visited[i] = True 45 | BFS(graph,visited) 46 | 47 | 48 | BFS(graph,visited) 49 | -------------------------------------------------------------------------------- /알고리즘 이론/147pg_BFS/solution.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | graph = [[], [2, 3, 8], 4 | [1, 7], 5 | [1, 4, 5], 6 | [3, 5], 7 | [3, 4], 8 | [7], 9 | [2, 6], 10 | [1, 7]] 11 | 12 | visited = [False] * 9 13 | 14 | 15 | def BFS(graph, n, visited): 16 | queue = deque([n]) 17 | visited[n] = True 18 | while queue: 19 | v = queue.popleft() 20 | print('{}번째 노드'.format(v)) 21 | for i in graph[v]: 22 | if not visited[i]: 23 | queue.append(i) 24 | visited[i] = True 25 | 26 | 27 | BFS(graph, 1, visited) -------------------------------------------------------------------------------- /알고리즘 이론/149pg_음료수 얼려 먹기/readme.md: -------------------------------------------------------------------------------- 1 | ##음료수 얼려먹기 2 | 3 | N * M 크기의 얼음 틀이 있다. 구멍이 뚫려 있는 부분은 0, 칸막이가 존재하는 부분은 1로 4 | 표시된다. 구멍이 뚫려 있는 부분끼리 상, 하, 좌, 우로 붙어있는 경우 서로 연결되어있는 것으로 간주한다. 이때 얼음 틀의 모양이 주어졌을 떄 생성되는 총 아이스크림의 개수를 구하는 프로그램을 작성하시오. 다음의 4 * 5 얼음틀 예시에서는 아이스크림이 총 3개 생성된다. 5 | 6 | 입력조건 7 | - 첫 번째 줄에 얼음 틀의 세로길이 N과 가로 길이 M이 주어진다.(1 <= N, M <= 1000) 8 | - 두 번째 줄부터 N + 1번째 줄 까지 얼음 틀의 형태가 주어진다. 9 | - 이때 구멍이 뚫려 있는 부분은 0, 그렇지 않은 부분은 1이다. 10 | 11 | 출력조건 12 | - 한 번에 만들수 있는 아이스크림의 개수를 출력한다. 13 | 14 | 4 5 15 | 00110 16 | 00011 17 | 11111 18 | 00000 19 | 20 | 21 | ####Tip 22 | 1. 현재 주어진 맵은 이중배열로 인식하자 23 | 24 | 2. DFS개념을 적용하여 특정지점에서 부터 방문을 시작하자 25 | 26 | 3. 방문한 지점은 얼음으로 만들어서 방문하지 못하도록 인식 27 | 28 | 4. 방문한다는 개념을 가질때 DFS 재귀를 넣어서 연결된다는 조건을 만족하면 True 29 | 30 | 5. DFS 재귀의 끝내는 마무리 조건을 False로 넣어서 재귀 탈출 조건을 만들어줌 -------------------------------------------------------------------------------- /알고리즘 이론/149pg_음료수 얼려 먹기/solution.py: -------------------------------------------------------------------------------- 1 | N, M = map(int,input().split()) 2 | board = [] 3 | 4 | for i in range(N): 5 | board.append(list(map(int,input()))) 6 | 7 | #print(N,M,board) 8 | 9 | result = 0 10 | 11 | def DFS(board,x,y): 12 | if x<0 or x>=N or y<0 or y>=M: 13 | return False 14 | elif board[x][y] == 1: 15 | return False 16 | else: 17 | #print('{},{}방문'.format(x,y)) 18 | board[x][y] = 1 19 | DFS(board, x -1, y) 20 | DFS(board, x, y-1) 21 | DFS(board,x+1,y) 22 | DFS(board,x,y+1) 23 | return True 24 | #DFS(list,x+1,y+1) 25 | 26 | 27 | 28 | for i in range(N): 29 | for j in range(M): 30 | if DFS(board,i,j)==True: 31 | #print('{},{}시작점'.format(i,j)) 32 | result += 1 33 | 34 | print(result) -------------------------------------------------------------------------------- /알고리즘 이론/152pg_미로 탈출/readme.md: -------------------------------------------------------------------------------- 1 | ##미로 탈 2 | 3 | 동빈이는 N * M 크기의 직사각형 형태의 미로에 갇혀 있다. 4 | 미로에는 여러 마리의 괴물이 있어 이를피해 탈출해야한다. 5 | 동빈이의 위치는 (1, 1)이고 미로의 출구는 (N, M)의 위치에 존재하며 한 번에 한 칸씩 이동할 수 있다. 6 | 이때 괴물이 있는 부분은 0으로, 괴물이 없는 부분은 1로 표시되어 있다. 7 | 미로는 반드시 탈출할 수 있는 형태로 제시된다. 이때 동빈이가 탈출하기 위해 움직여야 하는 최소 칸의 개수를 구하시오. 8 | 칸을 셀 떄는 시작 칸과 마지막 칸을 모두 포함해서 계산한다. 9 | 10 | 입력조건 11 | - 첫째 줄에 두 정수 N, M(4 <= N, M <= 200)이 주어집니다. 12 | 다음 N개의 줄에는 각각 M개의 정수(0혹은 1)로 미로의 정보가 주어진다. 13 | 각각의 수들은 공백 없이붙어서 입력으로 제시된다. 또한 시작 칸과 마지막 칸은 항상 1이다. 14 | 15 | 출력조건 16 | - 첫째 줄에 최소 이동 칸의 개수를 출력한다. 17 | 18 | 19 | 20 | ####Tip 21 | 1. BFS는 deque를 사용하며 재귀함수를 사용하지 않는다. 다만 queue가 비워질 때까지 동작한다. 22 | 23 | 2. 맵에 대한 방문을 시도할 때는 4가지 방위를 설정해서 풀어보자 24 | 25 | 3. 노드의 방문 처리와 최소 길이는 맵을 클론하여 방문처리 및 거리를 축적하자 26 | 27 | 4. 현재 방문 처리는 딱히 안해도 된다. 조건만 만족하면 큐에 삽입하면 되고 28 | 29 | 거리를 축적할 때도 그래프 자체에 거리를 축적하면 같은 의미이다. 30 | 따라서 위코드를 간단히 하면 answer[nx][ny] = answer[x][y] + 1 대신 31 | graph[nx][ny] = graph[x][y] + 1을 넣고 visited 맵과 answer 맵을 삭제하면 된다. 32 | 33 |


34 | ######입력 데이터 35 | 5 6
36 | 101010
37 | 111111
38 | 000001
39 | 111111
40 | 111111
41 | 42 | 43 | -------------------------------------------------------------------------------- /알고리즘 이론/152pg_미로 탈출/solution.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | N, M = map(int,input().split()) 4 | 5 | data = [] 6 | 7 | for _ in range(N): 8 | data.append(list(map(int,input()))) 9 | 10 | print(data) 11 | 12 | dx = [0,0,-1,1] 13 | dy = [1,-1,0,0] 14 | 15 | def BFS(data): 16 | queue = deque() 17 | x = 0 18 | y = 0 19 | D = 1 20 | queue.append((x,y,D)) 21 | while queue: 22 | tmp = queue.popleft() 23 | x = tmp[0] 24 | y = tmp[1] 25 | D = tmp[2] + 1 26 | for i in range(4): 27 | tmp_x = x+dx[i] 28 | tmp_y = y+dy[i] 29 | if tmp_x < 0 or tmp_y < 0 or tmp_x >= N or tmp_y >= M: 30 | continue 31 | elif data[tmp_x][tmp_y] ==1: 32 | if tmp_x == 0 and tmp_y == 0: 33 | continue 34 | else: 35 | print('({},{})방문 값 = {}'.format(tmp_x, tmp_y, D)) 36 | data[tmp_x][tmp_y] = D 37 | ##여기에 return 조건을 넣으면 빠르게 종료 38 | ##바깥에 return 조건을 넣으면 가능한 경로 모두 탐색후 종료 39 | queue.append((tmp_x, tmp_y,D)) 40 | return data[N-1][M-1] 41 | 42 | print(BFS(data)) 43 | 44 | 45 | -------------------------------------------------------------------------------- /알고리즘 이론/159pg_선택정렬/readme.md: -------------------------------------------------------------------------------- 1 | ##선택정렬 2 | 3 | 가장 작은 데이터를 선택하여 정렬을 반복한다. 4 | 5 | N개의 입력값에서 가장작은 값을 선택 해야 하므로 N번의 비교를 한뒤 정렬 6 | 7 | 정렬된 1개를 제외한 N-1개 중 가장 작은 값을 선택 해야 하므로 N-1번의 비교를 한뒤 정렬 8 | 9 | 따라서 N + (N-1) + (N-2) + ... 10 | 11 | (N^2 + N) / 2 12 | 13 | 따라서 시간복잡도는 O(N^2)이 됨. 14 | 15 | -------------------------------------------------------------------------------- /알고리즘 이론/159pg_선택정렬/solution.py: -------------------------------------------------------------------------------- 1 | array = [7,5,9,0,3,1,6,2,4,8] 2 | #0~9 3 | for i in range(len(array)): 4 | min_idx = i 5 | for j in range(i+1,len(array)): 6 | if array[min_idx] > array[j]: 7 | min_idx = j 8 | array[i], array[min_idx] = array[min_idx],array[i] 9 | 10 | print(array) -------------------------------------------------------------------------------- /알고리즘 이론/165pg_삽입 정렬/readme.md: -------------------------------------------------------------------------------- 1 | ##삽입 정렬 2 | 3 | 인덱스 번호 0번 부터 마지막 인덱스까지 순차적으로 확인하며 본인 보다 크거나 작은 값이 인덱스 앞에 있을경우 swap한다. 4 | 5 | 이미 많이 정렬되어 있는 리스트의 경우에 유용하며 6 | 7 | 입력값이 N개일때 최악의 경우 역으로 정렬되어 있어서, N + (N-1) + (N-2) + ..만큼 비교하고 swap해야 하므로 8 | 9 | 시간복잡도는 O(N^2)으로 볼 수 있다. -------------------------------------------------------------------------------- /알고리즘 이론/165pg_삽입 정렬/solution.py: -------------------------------------------------------------------------------- 1 | array = [7,5,9,0,3,1,6,2,4,8] 2 | """ 3 | for i in range(1,len(array)-1): 4 | tmp1 = array[i] 5 | idx = i 6 | for j in range(i,-1,-1): 7 | tmp2 = array[j] 8 | 9 | if tmp2 > tmp1: 10 | array[idx], array[j] = array[j] , array[idx] 11 | idx = j 12 | 13 | print(array) 14 | """ 15 | for i in range(1,len(array)): 16 | for j in range(i,0,-1): 17 | if array[j] < array[j-1]: 18 | array[j], array[j-1] = array[j-1] , array[j] 19 | else: 20 | break 21 | print(array) -------------------------------------------------------------------------------- /알고리즘 이론/168pg_퀵 정렬/readme.md: -------------------------------------------------------------------------------- 1 | ##퀵 정렬 2 | 3 | 퀵 정렬은 '피벗'과 '분할'을 활용하여 정렬한다. 4 | 5 | 정렬의 0번 인덱스값을 음'피벗'으로 결정한 다음 리스트를 돌며 피벗보다 작은 값과 피벗보다 큰 값을 분리하여 리스트를 분할한다. 6 | 7 | 즉 피벗을 제외한 리스트에서 왼쪽 index와 오른쪽 index를 지정하고 왼쪽 index는 오른쪽으로 이동하며 피벗값보다 8 | 9 | 클경우 stop, 오른쪽 index는 왼쪽으로 이동하며 피벗값보다 작을 경우 stop하여 두개의 값을 swap한다. 10 | 11 | 위과정을 반복한뒤 왼쪽 index와 오른쪽 index가 교차(왼쪽인덱스가 오른쪽인덱스보다 커지는순간)되는경우 작은 값과 12 | 13 | 피벗의 값을 swap한 뒤 피벗값을 기준으로 양쪽의 두개의 List에서 다시 퀵정렬을 수행한다. 14 | 15 | 시간복잡도는 O(NlogN)으로 선택정렬과 삽입정렬에 비해 빠르다. 최악의 경우는 O(N^2) 16 | 17 | 삽입 정렬과 반대로 이미 정렬이 되어있는 경우 느리게 작동하고, 무작위로 들어가 있는 경우 빠르게 작동한다. 18 | 19 | [장점]퀵정렬의 효율성 20 | - 평균적으로 가장 빠르게 동작하는 정렬방식이다. 21 | - 리스트의 특성을 파악하기 어려운 상태라면 퀵정렬을 사용하는 것이 가장 적절하다. 22 | -------------------------------------------------------------------------------- /알고리즘 이론/168pg_퀵 정렬/solution.py: -------------------------------------------------------------------------------- 1 | array = [5,7,9,0,3,1,6,2,4,8] 2 | 3 | def quick_sort(array): 4 | if len(array) <= 1: 5 | return array 6 | 7 | pivot = array[0] 8 | new_array = array[1:] 9 | 10 | left_side = [x for x in new_array if x <= pivot] 11 | right_side = [x for x in new_array if x> pivot] 12 | 13 | return quick_sort(left_side) + [pivot] + quick_sort(right_side) 14 | 15 | quick_sort(array) 16 | 17 | -------------------------------------------------------------------------------- /알고리즘 이론/174pg_계수정렬/readme.md: -------------------------------------------------------------------------------- 1 | ##계수정렬 2 | 3 | 가장 큰 데이터와 가장 작은 데이터의 차이가 1,000,000을 넘지 않을때 사용하는 효과적인 방법 4 | 5 | 값을 비교하여 정렬을 하는 방식이 아닌 가장 큰 데이터의 크기만큼의 리스트를 만들고 6 | 7 | 정렬할 리스트의 값들을 모두 세어 새로만든 리스트의 값에 추가하는 방식이다. 8 | 9 | 데이터중 최댓값이 K라 할때 시간복잡도는 O(N+K), 공간복잡도는 O(K) 10 | 11 | 12 | [단점]계수정렬의 비효율성 13 | - 정렬해야할 리스트 0과 999,999 두값로 이루어 졌다고 할때, 두 값을 비교할경우 한번의 연산으로 정렬할 수 있지만, 14 | 계수정렬을 사용할 경우, 의미없는 공간 999,999개를 필요로한다. 15 | 16 | [장점]계수정렬의 효율성 17 | - 같은값이 여러번 존재하는 리스트의 정렬시에 유용하다. 18 | - 입력값을 1000만개 이상으로 설정할수 없는 경우가 많기 때문에 걔수정렬 또한 효과적인 경우가 많다. 19 | 20 | [참고]기수정렬 21 | -------------------------------------------------------------------------------- /알고리즘 이론/174pg_계수정렬/solution.py: -------------------------------------------------------------------------------- 1 | array = [7,5,9,0,3,1,6,2,9,1,4,8,0,5,2] 2 | 3 | count = [0 for _ in range(max(array)+1)] 4 | 5 | for val in array: 6 | count[val] += 1 7 | 8 | 9 | for x in range(len(count)): 10 | for val in range(count[x]): 11 | print(x, end=' ') 12 | 13 | -------------------------------------------------------------------------------- /알고리즘 이론/176pg_파이썬 정렬/readme.md: -------------------------------------------------------------------------------- 1 | 파이썬의 정렬라이브러리 sorted or sort 를 사용하게 될 경우, 최악의 경우에도 NlogN의 시간복잡도를 보장한다. 2 | -------------------------------------------------------------------------------- /알고리즘 이론/176pg_파이썬 정렬/solution.py: -------------------------------------------------------------------------------- 1 | array1 = [7,5,9,0,3,1,6,2,4,8] 2 | 3 | result = sorted(array1) 4 | 5 | print(result) 6 | 7 | print("===================================") 8 | 9 | array2 = [7,5,9,0,3,1,6,2,4,8] 10 | 11 | array2.sort() 12 | 13 | print(array2) 14 | 15 | print("===================================") 16 | 17 | array3 = [('바나나',2),('사과',5),('당근',3)] 18 | 19 | def setting(data): 20 | return data[1] 21 | 22 | result = sorted(array3,key=setting) 23 | 24 | print(result) 25 | 26 | print("===================================") 27 | 28 | array4 = [('바나나',2),('사과',5),('당근',3)] 29 | 30 | result = sorted(array4,key=lambda x:x[1]) 31 | 32 | print(result) 33 | 34 | -------------------------------------------------------------------------------- /알고리즘 이론/178pg_위에서 아래로/solution.py: -------------------------------------------------------------------------------- 1 | n = int(input()) 2 | list = [] 3 | for i in range(n): 4 | list.append(int(input())) 5 | 6 | result = sorted(list, reverse=True) 7 | 8 | for i in result: 9 | print(i,end=' ') 10 | -------------------------------------------------------------------------------- /알고리즘 이론/180pg_성적이 낮은 순서로 학생 출력하기/solution.py: -------------------------------------------------------------------------------- 1 | n = int(input()) 2 | 3 | list = [] 4 | 5 | for i in range(n): 6 | input_data = input().split() 7 | list.append((input_data[0],int(input_data[1]))) 8 | 9 | result = sorted(list,key = lambda student:student[1]) 10 | 11 | for x in result: 12 | print(x[0],end=' ') -------------------------------------------------------------------------------- /알고리즘 이론/182pg_두 배열의 원소 교체/solution.py: -------------------------------------------------------------------------------- 1 | N,K = map(int,input().split()) 2 | 3 | A = list(map(int,input().split())) 4 | B = list(map(int,input().split())) 5 | 6 | A.sort() 7 | B.sort(reverse=True) 8 | 9 | for i in range(K): 10 | if A[i] < B[i]: 11 | A[i], B[i] = B[i], A[i] 12 | else: 13 | break 14 | 15 | print(sum(A)) -------------------------------------------------------------------------------- /알고리즘 이론/187pg_순차탐색/readme.md: -------------------------------------------------------------------------------- 1 | ##순차탐색 2 | 3 | 리스트 안에있는 특정한 데이터를 찾기 위해 앞에서부터 데이터를 하나씩 차례대로 확인하는 방법 4 | 5 | 시간복잡도 O(N) 6 | -------------------------------------------------------------------------------- /알고리즘 이론/187pg_순차탐색/solution.py: -------------------------------------------------------------------------------- 1 | def sequential_search(n, target, array): 2 | for i in range(n): 3 | if array[i] == target: 4 | return i+1 5 | 6 | print("생성할 원소 개수를 입력한 다음 한 칸 띄고 찾을 문자열을 입력하세요.") 7 | input_data = input().split() 8 | n = int(input_data[0]) 9 | target = input_data[1] 10 | 11 | print("앞서 적은 원소 개수만큼 문자열을 입력하세요. 구분은 띄어쓰기 한 칸으로 합니다.") 12 | array = input().split() 13 | print(sequential_search(n,target,array)) -------------------------------------------------------------------------------- /알고리즘 이론/188pg_이진탐색/readme.md: -------------------------------------------------------------------------------- 1 | ##이진탐색 2 | - 반으로 쪼개면서 탐색하기 3 | 4 | 데이터가 정렬 되어 있는 경우, 매우 빠르게 데이터를 찾을 수 있지만 데이터가 정렬되어 있지 않는경우 사용할 수 없다. 5 | 포인트는 중간점으로, 찾으려는 데이터와 중간점 위치에 있는 데이터를 반복적으로 비교하여 원하는 데이터를 찾는 방식이다. 6 | 7 | 시간복잡도는 절반씩 줄여나가므로 O(logN) 8 | 9 | [추가]이진탐색트리 10 | - 부모노드보다 왼쪽 자식노드가 더 작다 11 | - 부모노드보다 오른쪽 자식노드가 더 크다 12 | - 왼쪽자식노드 < 부모노드 < 오른쪽자식노드 13 | 데이터의 개수가 1000만개를 넘어가거나 탐색 범위의 크기가 1000억 이상일경우 이진탐색 알고리즘을 의심해봐야 한다. 14 | 만약 데이터의 개수가 많은경우 input() 대신 sys.stdin.readline().rstrip()을 사용하도록한다. 15 | 이는 하나의 문자열로 인식하여 입력을 받도록한다. -------------------------------------------------------------------------------- /알고리즘 이론/188pg_이진탐색/solution.py: -------------------------------------------------------------------------------- 1 | #재귀함수 풀이 2 | """ 3 | def binary_search(array, target, start, end): 4 | if start>end: 5 | return None 6 | mid = (start + end) // 2 7 | #print("array[mid] : ", array[mid],", start : ",start, ", end : ", end) 8 | if target == array[mid]: 9 | return mid + 1 10 | elif target > array[mid]: 11 | return binary_search(array,target,mid + 1,end) 12 | else: 13 | return binary_search(array,target,start,mid - 1) 14 | 15 | n, target = list(map(int,input().split())) 16 | array = list(map(int,input().split())) 17 | 18 | result = binary_search(array,target,0,n-1) 19 | if result == None: 20 | print("원소가 존재하지 않습니다.") 21 | else: 22 | print(result) 23 | """ 24 | 25 | #반복문 코드 26 | 27 | n, target = list(map(int,input().split())) 28 | array = list(map(int,input().split())) 29 | 30 | start = 0 31 | end = n-1 32 | def binary_search(array,target,start,end): 33 | while start <= end: 34 | mid = (start + end) // 2 35 | if array[mid] == target: 36 | return mid 37 | elif array[mid] > target: 38 | end = mid - 1 39 | else: 40 | start = mid + 1 41 | return None 42 | 43 | result = binary_search(array,target,start,end) 44 | if result!=None: 45 | print(result) 46 | else: 47 | print("원소가 존재하지 않습니다.") 48 | 49 | -------------------------------------------------------------------------------- /알고리즘 이론/197pg_부품찾기/readme.md: -------------------------------------------------------------------------------- 1 | [참고] 2 | 3 | - 데이터의 범위가 1,000,000 이상인 경우 계수정렬사용 불가 4 | - set자료형은 데이터의 유무 확인에 효율적 5 | - 이진탐색을 고려.. 최악의 경우, 이진탐색을 사용하기 위하여 리스트를 정렬하는 과정의 시간복잡도 O(NlogN) 약 2000만번, 6 | 부품을 찾는 과정에서 시간복잡도 O(MlogN) 약 200만번, 총 시간복잡도는 O((M+N)logN) -------------------------------------------------------------------------------- /알고리즘 이론/197pg_부품찾기/solution.py: -------------------------------------------------------------------------------- 1 | #이진탐색 알고리즘 2 | """ 3 | def binary_search(array,target,start,end): 4 | while start <= end: 5 | mid = (start + end)//2 6 | if array[mid] == target: 7 | return mid 8 | elif array[mid] > target: 9 | end = mid - 1 10 | else: 11 | start = mid + 1 12 | return None 13 | 14 | 15 | N = int(input()) 16 | array1 = list(map(int,input().split())) 17 | M = int(input()) 18 | array2 = list(map(int,input().split())) 19 | array1.sort() 20 | 21 | 22 | for target in array2: 23 | result = binary_search(array1,target,0,N-1) 24 | if result == None: 25 | print("no", end= ' ') 26 | else: 27 | print("yes",end = ' ') 28 | 29 | """ 30 | #계수정렬 알고리즘 31 | """ 32 | N = int(input()) 33 | array1 = list(map(int,input().split())) 34 | M = int(input()) 35 | array2 = list(map(int,input().split())) 36 | array1.sort() 37 | 38 | max_val = max(array1) 39 | count = [0] * (max_val+1) 40 | 41 | for data in array1: 42 | count[data] += 1 43 | 44 | for find_data in array2: 45 | if count[find_data] != 0: 46 | print("yes",end = ' ') 47 | else: 48 | print("no", end = ' ') 49 | """ 50 | 51 | #set자료형을 이용한 데이터 유무 확인 52 | N = int(input()) 53 | array1 = set(map(int,input().split())) 54 | 55 | M = int(input()) 56 | array2 = list(map(int, input().split())) 57 | 58 | for x in array2: 59 | if x in array1: 60 | print("yes",end = ' ') 61 | else: 62 | print("no",end = ' ') 63 | 64 | -------------------------------------------------------------------------------- /알고리즘 이론/201pg_떡볶이 떡 만들기/solution.py: -------------------------------------------------------------------------------- 1 | N, M = map(int,input().split()) 2 | array = list(map(int,input().split())) 3 | 4 | def binary_search(array,target,start,end): 5 | while start <= end: 6 | mid = (start + end)//2 7 | sum = 0 8 | for i in array: 9 | if i>mid: 10 | sum += i-mid 11 | #print("sum : " , sum, " mid : " , mid) 12 | if sum == target: 13 | #print("찾았습니다!") 14 | return mid 15 | elif sum > target: 16 | #print("오른쪽으로 이동") 17 | start = mid + 1 18 | else: 19 | #print("왼쪽으로 이동") 20 | end = mid - 1 21 | return None 22 | 23 | start = 0 24 | end = max(array) 25 | print("end : " , end) 26 | result = binary_search(array,M,start,end) 27 | print(result) 28 | -------------------------------------------------------------------------------- /알고리즘 이론/214pg_다이나믹 프로그래밍/solution.py: -------------------------------------------------------------------------------- 1 | d = [0] * 100 2 | 3 | def fibo(n): 4 | if n == 1 or n == 2: 5 | return 1 6 | if d[n] != 0: 7 | return d[n] 8 | else: 9 | d[n] = fibo(n-1) + fibo(n-2) 10 | return d[n] 11 | 12 | print(fibo(6)) 13 | 14 | 15 | -------------------------------------------------------------------------------- /알고리즘 이론/217pg_1로 만들기/readme.md: -------------------------------------------------------------------------------- 1 | ##다이나믹 프로그래밍 2 | 3 | - 문제에 대한 접근이 어렵다고 느껴지면 트리를 그려 볼 것. 4 | 5 | - 반복되는 연산에 대해서 값을 미리 저장해 두었다가 꺼내는 방식 6 | 7 | - 매계산마다 최솟값을 저장해 둔다고 생각할 것 8 | 9 | - 탑다운(메모이제이션, 하향식)방식과 보텀업(상향식)방식 두가지가 존재 10 | 11 | - 보통은 보텀업 방식을 사용. -------------------------------------------------------------------------------- /알고리즘 이론/217pg_1로 만들기/solution.py: -------------------------------------------------------------------------------- 1 | X = int(input()) 2 | 3 | d = [0] * 30001 4 | 5 | for i in range(2,X+1): 6 | d[i] = d[i-1] + 1 7 | if i%2==0: 8 | d[i] = min(d[i],d[i//2] + 1) 9 | if i%3 == 0: 10 | d[i] = min(d[i],d[i//3] + 1) 11 | if i%5 == 0: 12 | d[i] = min(d[i],d[i//5] + 1) 13 | 14 | print(d[X]) -------------------------------------------------------------------------------- /알고리즘 이론/220pg_개미 전사/solution.py: -------------------------------------------------------------------------------- 1 | N = int(input()) 2 | 3 | array = list(map(int,input().split())) 4 | 5 | d = [0] * 101 6 | 7 | d[0] = array[0] 8 | d[1] = array[1] 9 | 10 | for i in range(2, N): 11 | d[i] = max(d[i-1], d[i-2]+array[i]) 12 | print(d[N-1]) -------------------------------------------------------------------------------- /알고리즘 이론/223pg_바닥공사/solution.py: -------------------------------------------------------------------------------- 1 | N = int(input()) 2 | 3 | d = [0] * 1001 4 | d[1] = 1 5 | d[2] = 3 6 | 7 | for i in range(3,N+1): 8 | d[i] = (d[i-2]*2 + d[i-1]) % 796796 9 | #print("i : ", i) 10 | 11 | print(d[n]) -------------------------------------------------------------------------------- /알고리즘 이론/226pg_효율적인 화폐 구성/solution.py: -------------------------------------------------------------------------------- 1 | N, M = map(int,input().split()) 2 | 3 | coins = [] 4 | d = [10001] * 10001 5 | d[0] = 0 6 | for i in range(N): 7 | coins.append(int(input())) 8 | 9 | 10 | for i in range(N): 11 | #print("coins[i] : ", coins[i]) 12 | for j in range(coins[i],M+1): 13 | if d[j-coins[i]] != 10001: 14 | #print("Enter j : ", j ) 15 | d[j] = min(d[j],d[j-coins[i]]+1) 16 | 17 | if d[M] == 10001: 18 | print(-1) 19 | else: 20 | print(d[M]) 21 | -------------------------------------------------------------------------------- /알고리즘 이론/238pg_다익스트라 알고리즘/readme.md: -------------------------------------------------------------------------------- 1 | ##다익스트라 알고리즘 2 | 3 | V : 노드의 개수 4 | V^2 <= 25,000,000 일때 O(V^2)이 성립하여 사용 가능 5 | 6 | 1. start 노드를 방문한뒤 distance를 0으로 설정(visited 또한 True로 설정) 7 | 8 | 2. start 노드와 연결된 노드를 distance에 기록(visited가 된 경우 방문 X) distance[start] + 연결된 노드와의 거리 9 | 10 | 3. start 노드에 대한 기록이 끝나면 다른 노드들 중 작은 distance를 가지는 노드 순서대로 방문 11 | 12 | 4. 노드와 연결된 다른 노드를 distance에 기록(visited가 된 경우 방문 X) distance[현재노드] + 연결된 노드와의 거리 13 | 14 | 5. 모든 노드가 방문이 될 때 까지 3~4번 과정을 반복 15 | -------------------------------------------------------------------------------- /알고리즘 이론/238pg_다익스트라 알고리즘/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | INF = int(1e9) 4 | 5 | N, M = map(int,input().split()) 6 | start = int(input()) 7 | 8 | graph = [[] for _ in range(N+1)] 9 | 10 | visited = [False for _ in range(N+1)] 11 | 12 | distance = [INF for _ in range(N+1)] 13 | 14 | for i in range(M): 15 | tmp = list(map(int,input().split())) 16 | graph[tmp[0]].append((tmp[1],tmp[2])) 17 | 18 | def get_smallest_node(): 19 | min_value = INF 20 | idx = 0 21 | for i in range(1,N+1): 22 | if visited[i] == False: 23 | if min_value > distance[i]: 24 | min_value = distance[i] 25 | idx = i 26 | 27 | return idx 28 | 29 | def dijkstra(start): 30 | distance[start] = 0 31 | visited[start] = True 32 | for i in graph[start]: 33 | distance[i[0]] = i[1] 34 | 35 | print(distance) 36 | for i in range(N-1): 37 | now = get_smallest_node() 38 | visited[now] = True 39 | for j in graph[now]: 40 | cost = distance[now]+j[1] 41 | if cost < distance[j[0]]: 42 | distance[j[0]] = cost 43 | print(distance) 44 | 45 | dijkstra(start) 46 | -------------------------------------------------------------------------------- /알고리즘 이론/248pg_개선된 다익스트라 알고리즘/readme.md: -------------------------------------------------------------------------------- 1 | ##개선된 다익스트라 알고리즘 2 | 3 | 다익스트라 알고리즘과 동일. 4 | 5 | 대신 시간복잡도를 조금 줄일수 있는 방법이 존재. O(ElogV) 6 | 7 | 모든 노드들에 대한 간선을 확인하는 과정을 min heap을 통해 수행 8 | 9 | 1. (0(거리),start(노드)) 값을 heap에 저장 10 | 11 | 2. heap에서 거리가 가장 작은 노드를 pop 한 뒤, 해당 노드와 연결된 노드들을 탐색. 12 | 13 | 3. 연결된 노드들까지의 거리 + pop한 거리값을 distance에 저장한 뒤, 해당 노드에 연결된 노드들을 다시 heap에 push 14 | 15 | 4. 2~3번 과정을 반복 (heap이 빌 때까지) 16 | 17 | - 힙을 사용하지 않을 경우, N개의 노드들에 대해 순차 탐색을 진행하므로 N^2이 성립 18 | 19 | - 힙을 사용할 경우, N개의 노드들에 대한 순차탐색 없이 E개의 간선에 대해서 heap push, pop만 진행 되므로 O(ELogE)가 성립하고 logV^2 < logE 이므로 O(ElogV^2)가 성립. 이는 O(ElogV)로 정리가능 20 | 21 | 즉 노드의 개수가 5000개 이하라면 일반적인 다익스트라 알고리즘으로 해결가능 22 | 23 | 노드의 개수가 10000개 이상이라면 개선된 다익스트라 알고리즘으로 해결가능. 24 | -------------------------------------------------------------------------------- /알고리즘 이론/248pg_개선된 다익스트라 알고리즘/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import heapq 3 | input = sys.stdin.readline 4 | INF = int(1e9) 5 | 6 | N, M = map(int,input().split()) 7 | start = int(input()) 8 | 9 | graph = [[] for _ in range(N+1)] 10 | 11 | distance = [INF for _ in range(N+1)] 12 | 13 | for i in range(M): 14 | tmp = list(map(int,input().split())) 15 | graph[tmp[0]].append((tmp[1],tmp[2])) 16 | 17 | 18 | def dijkstra(start): 19 | q = [] 20 | 21 | heapq.heappush(q, (0,start)) 22 | distance[start] = 0 23 | 24 | while q: 25 | tmp = heapq.heappop(q) 26 | dist, now = tmp[0], tmp[1] 27 | if distance[now] < dist: 28 | continue 29 | 30 | for i in graph[now]: 31 | cost = dist+i[1] 32 | if distance[i[0]] > cost: 33 | distance[i[0]] = cost 34 | heapq.heappush(q,(cost,i[0])) 35 | 36 | dijkstra(start) -------------------------------------------------------------------------------- /알고리즘 이론/258pg_플로이드 워셜 알고리즘/readme.md: -------------------------------------------------------------------------------- 1 | ##플로이드 워셜 알고리즘 2 | 3 | NxN 의 메트릭스를 이용하여 출발노드->도착노드 의 거리를 포함한다. 4 | 5 | 기본적인 개념은 모든 간선들을 미리 기록해둔 뒤 A노드 -> B노드로 이동할때 중간에 C노드를 거쳐갈 경우를 확인하여 더 작은 값을 채택하는 방식으로 진행한다. 6 | 7 | 각 단계마다 거쳐가는 노드를 탐색하므로 O(N^2)이며 모든 노드를 검색하려면 O(N^3)이 됨. 8 | 9 | 모든 노드 -> 다른 모든 노드까지의 모든 경로의 최단거리를 계산. 10 | 11 | 노드의 개수가 적은 경우 효과적으로 사용 가능.500이하 정도..? 500x500x500은 1억이 넘으므로 안될수도 있음. 12 | 13 | -------------------------------------------------------------------------------- /알고리즘 이론/258pg_플로이드 워셜 알고리즘/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | INF = int(1e9) 4 | 5 | V = int(input()) 6 | E = int(input()) 7 | 8 | board = [[INF for _ in range(V+1)] for _ in range(V+1)] 9 | 10 | for i in range(E): 11 | start,end,dist = map(int,input().split()) 12 | board[start][end] = dist 13 | 14 | for i in range(1,V+1): 15 | for j in range(1,V+1): 16 | if i == j: board[i][j] = 0 17 | else: 18 | for k in range(1,V+1): 19 | board[i][j] = min(board[i][j],board[i][k] + board[k][j]) 20 | 21 | 22 | 23 | for i in range(1,V+1): 24 | for j in range(1,V+1): 25 | if board[i][j]== INF: 26 | print("INF",end = ' ') 27 | else: 28 | print(board[i][j], end = ' ') 29 | print() 30 | 31 | -------------------------------------------------------------------------------- /알고리즘 이론/259pg_미래도시/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | INF = int(1e9) 3 | 4 | input = sys.stdin.readline 5 | 6 | 7 | N, M = map(int,input().split()) 8 | 9 | board = [[INF for _ in range(N+1)] for _ in range(N+1)] 10 | 11 | for i in range(1,N+1): 12 | for j in range(1,N+1): 13 | if i==j: board[i][j] = 0 14 | 15 | for i in range(M): 16 | start, end = map(int,input().split()) 17 | board[start][end] = 1 18 | board[end][start]= 1 19 | 20 | X,K = map(int,input().split()) 21 | 22 | for i in range(1,N+1): 23 | for j in range(1,N+1): 24 | for k in range(1,N+1): 25 | board[i][j] = min(board[i][j], board[i][k] + board[k][j] ) 26 | 27 | for i in range(1,N+1): 28 | for j in range(1,N+1): 29 | print(board[i][j], end= '\t') 30 | print() 31 | if board[1][K] + board[K][X] < INF: 32 | print(board[1][K] + board[K][X]) 33 | else: 34 | print(-1) -------------------------------------------------------------------------------- /알고리즘 이론/262pg_전보/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import heapq 3 | input = sys.stdin.readline 4 | 5 | INF = int(1e9) 6 | 7 | N,M,C = map(int,input().split()) 8 | 9 | graph = [[] for _ in range(N+1)] 10 | 11 | distance = [INF for _ in range(N+1)] 12 | 13 | for i in range(M): 14 | start, end, dist = map(int,input().split()) 15 | graph[start].append((end,dist)) 16 | 17 | #C = start 18 | 19 | def dijkstar(start): 20 | q = [] 21 | heapq.heappush(q,(0,start)) 22 | distance[start] = 0 23 | 24 | while q: 25 | tmp = heapq.heappop(q) 26 | dist, now = tmp[0], tmp[1] 27 | ##기억!! 28 | if distance[now] < dist: 29 | continue 30 | for i in graph[now]: 31 | end, dist = i[0], i[1] 32 | data = distance[now] + dist 33 | if distance[end] > data: 34 | distance[end] = data 35 | heapq.heappush(q,(data,end)) 36 | 37 | 38 | 39 | dijkstar(C) 40 | 41 | print(distance) 42 | country = 0 43 | max = -1 44 | for i in range(1,N+1): 45 | if distance[i] != INF and distance[i] != 0: 46 | country +=1 47 | if max < distance[i]: 48 | max = distance[i] 49 | 50 | print(country,max) 51 | -------------------------------------------------------------------------------- /알고리즘 이론/279pg_서로소 집합을 활용한 union-find 알고리즘/readme.md: -------------------------------------------------------------------------------- 1 | ##서로소 집합 연산 2 | 3 | 서로소 집합 자료구조는 union-find 구조로 find(찾기) 연산을 통해 각 노드의 root node를 찾고, 4 | 정해진 규칙(우선순위가 더 높은쪽으로)에 맞게 union(합집합) 합치기 과정이 수행된다. 5 | 6 | 즉 (1,2) (3,4) 두개의 서로소 집합이 union find 과정이 수행된다면 7 | 8 | | |1|2|3|4| 9 | |---|---|---|---|---| 10 | |parent|1|2|3|4| 11 | 12 | 과정에서 13 | 14 | | |1|2|3|4| 15 | |---|---|---|---|---| 16 | |parent|1|1|3|3| 17 | 18 | 으로 각각의 부모노드가 설정되고 두 서로소 집합 원소중 2와 4의 union 과정이 이루어 진다면 19 | 20 | | |1|2|3|4| 21 | |---|---|---|---|---| 22 | |parent|1|2|3|4| 23 | 24 | 2의 부모노드 1 , 4의 부모노드 3을 find 한 뒤, 두 노드 중 우선순위가 더 높은 1로 3,4 집합이 union 된다 25 | 26 | | |1|2|3|4| 27 | |---|---|---|---|---| 28 | |parent|1|2|1|4| 29 | 30 | 빠른 동작을 위해서는 31 | 32 | | |1|2|3|4| 33 | |---|---|---|---|---| 34 | |parent|1|1|1|4| 35 | 36 | 2와 3노드의 부모노드를 모두 1로 설정하는 방법이 있다.(경로압축) -------------------------------------------------------------------------------- /알고리즘 이론/279pg_서로소 집합을 활용한 union-find 알고리즘/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | 4 | def find_parent(parent,x): 5 | if parent[x] != x: 6 | parent[x] = find_parent(parent,parent[x]) 7 | return parent[x] 8 | 9 | 10 | def union_parent(parent,a,b): 11 | a = find_parent(parent,a) 12 | b = find_parent(parent,b) 13 | 14 | if a 크루스칼 알고리즘(그리디 알고리즘) 12 | 13 | ##크루스칼 알고리즘(그리디 알고리즘) 14 | 1. 간선 데이터를 비용에 따라 오름차순 정렬. 15 | 2. 간선을 하나씩 확인하여 싸이클이 발생하는지 확인. 16 | 1. 사이클이 발생하는 경우, 최소 신장 트리에 포함X 17 | 2. 사이클이 발생하지 않는 경우, 최소 신장 트리에 포함 18 | 3. 모든 간선에 대하여 2번 과정 반복. -------------------------------------------------------------------------------- /알고리즘 이론/288pg_크루스칼 알고리즘/readme.md: -------------------------------------------------------------------------------- 1 | ##크루스칼 알고리즘 2 | 3 | 최소 신장 트리를 구성하는 방법. 4 | 5 | 비용의 합이 최소가 되기 위해 정렬이 우선시 되어야 함. 6 | 7 | 같은 부모일 경우 패스, 8 | 9 | 다른 부모일 경우 union후 비용 추가 10 | 11 | edges.append((cost,a,b)) 12 | ()튜플을 이용하여 append 할경우 파이썬 자체 내에서 첫 번째 원소 cost 를 기준으로 정렬을 해서 넣어줌 13 | 14 | 크루스칼 알고리즘의 가장 오래 걸리는 작업은 정렬 15 | 16 | 따라서 정렬의 시간복잡도에 의존 17 | 18 | O(ElogE)가 성립. -------------------------------------------------------------------------------- /알고리즘 이론/288pg_크루스칼 알고리즘/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | 4 | def find_parent(parent,x): 5 | if parent[x] != x: 6 | parent[x] = find_parent(parent,parent[x]) 7 | return parent[x] 8 | 9 | def union_parent(parent,a,b): 10 | a = find_parent(parent,a) 11 | b = find_parent(parent,b) 12 | if a 알고리즘 8 | 자료구조 -> 고급알고리즘 9 | 알고리즘 -> 고급알고리즘 10 | 11 | 의 사이클이 없는 방향그래프가 존재한다고 할때, 방향에 맞게 고급알고리즘을 수행하기 위해서는 12 | 13 | 자료구조 -> 알고리즘 -> 고급알고리즘 순으로 수강해야 함. 14 | 15 | [keypoint] 16 | - 진입차수 : 특정한 노드로 들어오는 간선의 수 17 | - 진출차수 : 특정한 노드에서 나가는 간선의 수 18 | 19 | 20 | 1. 큐를 이용한 위상정렬 알고리즘 21 | 1. 진입차수가 0인 모든 노드들을 큐에 넣는다. 22 | 2. 큐가 빌때까지 다음 과정을 반복 23 | 1. 큐에서 원소를 꺼내 해당 노드에서 나가는 간선을 그래프에서 제거한다. 24 | 2. 새로운 진입차수가 0이 된 노드를 큐에 넣는다. 25 | 26 | -> 각 노드가 큐에 들어온 순서가 위상 정렬을 수행한것과 같은 결과를 갖음. 27 | 28 | 29 | [위상정렬의 특징] 30 | 31 | 1. 위상정렬은 DAG에서만 수행가능하다. 32 | - DAG: 순환하지 않는 방향 그래프 33 | 2. 위상정렬은 여러가지 답이 존재할 수 있다. 34 | - 한단계에서 큐에 새롭게 들어가는 원소가 2개이상 존재한다면 여러가지 답이 가능하다. 35 | 3. 모든 노드를 방문하기 전에 큐가 빈다면, 사이클이 존재한다고 볼 수 있다. 36 | - 사이클에 포함되는 원소는 큐에 절대 들어갈 수 없기 때문에. 37 | 38 | [시간복잡도] 39 | - 모든 노드를 확인해가며 연결된 모든 간선들을 차례로 제거하므로 O(V+E) -------------------------------------------------------------------------------- /알고리즘 이론/290pg_위상정렬/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | 4 | from collections import deque 5 | 6 | V,E = map(int,input().split()) 7 | indegree = [0 for _ in range(V+1)] 8 | graph = [[]for _ in range(V+1)] 9 | 10 | for _ in range(E): 11 | start,end = map(int,input().split()) 12 | graph[start].append(end) 13 | indegree[end] += 1 14 | 15 | def topology_sort(): 16 | result = [] 17 | q = deque() 18 | 19 | for i in range(1,V+1): 20 | if indegree[i] == 0: 21 | q.append(i) 22 | 23 | while q: 24 | now = q.popleft() 25 | result.append(now) 26 | for i in graph[now]: 27 | indegree[i] -= 1 28 | 29 | if indegree[i] == 0: 30 | q.append(i) 31 | 32 | return result 33 | 34 | result = topology_sort() 35 | print(result) 36 | -------------------------------------------------------------------------------- /알고리즘 이론/298pg_팀 결성/solution.py: -------------------------------------------------------------------------------- 1 | import sys 2 | input = sys.stdin.readline 3 | 4 | N,M = map(int,input().split()) 5 | 6 | def find_parent(parent, x): 7 | if parent[x] != x: 8 | parent[x] = find_parent(parent,parent[x]) 9 | return parent[x] 10 | 11 | def union_parent(parent,a,b): 12 | a = find_parent(parent,a) 13 | b = find_parent(parent,b) 14 | if atmp_min: 11 | minimum = tmp_min 12 | elif minimum