구현에는 완전 탐색 유형과 시뮬레이션 유형이 있다.
완전 탐색은 모든 경우의 수를 주저 없이 다 계산하는 해결 방법을 의미하고, 시뮬레이션은 문제에서 제시한 알고리즘을 한 단계씩 차례대로 직접 수행해야 하는 문제 유형을 의미한다.
이번주 구현 복습은 난이도가 좀 어렵게 느껴져 문제를 푸는 것을 목표로 하는 것이 아니라 코드를 이해하는 것을 목표로 했습니다..! 😥😥
https://programmers.co.kr/learn/courses/30/lessons/60057
def solution(s):
least_length = len(s)
temp = 0
# 문자열의 길이를 반으로 자름
# 길이의 반을 넘어서면 어차피 두 문자열로 나뉘기 때문.
for i in range(1, len(s)//2 + 1):
# zip 함수에 문자열, n 전달
temp = zip(i, s)
if temp < least_length:
least_length = temp
return least_length
# 문자열을 n개 단위로 잘라 압축하고, 압축된 문자열의 길이를 반환해주는 함수
def zip(num, s):
i = 0
zip_list = []
while True:
if i+num > len(s):
zip_list.append(s[i:])
break
else:
zip_list.append(s[i:i+num])
i = i+num
my_zip = ""
before = zip_list[0]
count = 1
for i in range(1, len(zip_list)):
curr = zip_list[i]
# 앞에 나온 것과 계속 같은 것이 나온다면
if curr == before:
# 나온 횟수 저장
count += 1
# 앞에 나온 것과 다른 것이 나온다면
# 저장된 횟수만큼 압축 문자열에 추가
else:
if count == 1:
my_zip = my_zip + before
else:
my_zip = my_zip + str(count) + before
count = 1
before = curr
my_zip = my_zip + before
return len(my_zip)
https://programmers.co.kr/learn/courses/30/lessons/60061
def isValid(answer):
for x,y,a in answer:
if a==0:
if (x,y-1,0) in answer or (x-1,y,1) in answer or (x,y,1) in answer or y==0:
continue
else:
return False
if a==1:
if (x,y-1,0) in answer or (x+1,y-1,0) in answer or ((x-1,y,1) in answer and (x+1,y,1) in answer):
continue
else:
return False
return True
def solution(n, build_frame):
answer = set()
for x,y,a,b in build_frame:
if b==0:
answer.remove((x,y,a))
if not isValid(answer):
answer.add((x,y,a))
else:
answer.add((x,y,a))
if not isValid(answer):
answer.remove((x,y,a))
answer = [list(i) for i in answer]
answer.sort(key=lambda x:(x[0],x[1],x[2]))
return answer
https://www.acmicpc.net/problem/3190
# 끝을 만났을 때는 die
# apple -> 몸길이 +1,
# (0,0)부터 시작
def Solution():
time = 0
# 북동남서
snake_array = []
direction = {0:(0,1), 1:(1,0),2:(0,-1),3:(-1,0)}
dir = 0 # 동쪽
# empty:0, 사과:1, 뱀:2
nx,ny = 0,0
board[0][0] = 2 # start
snake_array.append([0,0])
# 끝날때까지 돌기
while(1):
time += 1
nx = nx + direction[dir][0]
ny = ny + direction[dir][1]
if not 0<= nx <N or not 0<= ny <N:
break
# apple
if board[nx][ny] == 1:
board[nx][ny] = 2 # 머리 이동
snake_array.append([nx,ny])
# empty
elif board[nx][ny] == 0:
board[nx][ny] = 2
snake_array.append([nx,ny])
del_x, del_y = snake_array.pop(0)
board[del_x][del_y] = 0
# snake 몸통
elif board[nx][ny] == 2:
break
if len(snake_dir) != 0 and time == snake_dir[0][0]:
time, new_dir = snake_dir.pop(0)
if new_dir == 'L': # 왼쪽
dir = (dir + 3) % 4
elif new_dir == 'D':
dir = (dir + 1) % 4
return time
# 오른쪽/ 왼쪽 방향 바꾸는 건 % 연산자 이용하여 쉽게 할 수 있음
# 왼쪽으로 돌리기 = (현재 방향 + 3) % 4
# 오른쪽으로 돌리기 = (현재 방향 + 1) % 4
# board
N = int(input())
board = [[0 for i in range(N)] for j in range(N)]
# apple 넣기
k = int(input())
apple_locs = []
for _ in range(k):
x, y = map(int, input().split())
board[x-1][y-1] = 1
# snake 시간, 방향
l = int(input())
# (sec, c(left) or d(right))
snake_dir = list(map(lambda x:[int(x[0]),str(x[1])],\
[input().split() for _ in range(l)]))
print(Solution())
https://www.acmicpc.net/problem/15686
from itertools import combinations
n,m=map(int, input().split())
maps=[]
for i in range(n):
maps.append(list(map(int, input().split())))
home=[]
chicken=[]
for i in range(n):
for j in range(n):
if maps[i][j]==1:
home.append((i,j))
elif maps[i][j]==2:
chicken.append((i,j))
pick_chicken=list(combinations(chicken,m))
result=[0]*len(pick_chicken)
for i in home:
for j in range(len(pick_chicken)):
a=100
for k in pick_chicken[j]:
temp=abs(i[0]-k[0])+abs(i[1]-k[1])
a=min(a,temp)
result[j]+=a
print(min(result))
https://programmers.co.kr/learn/courses/30/lessons/60059
def attach(x, y, M, key, board):
for i in range(M):
for j in range(M):
board[x+i][y+j] += key[i][j]
def detach(x, y, M, key, board):
for i in range(M):
for j in range(M):
board[x+i][y+j] -= key[i][j]
def rotate90(arr):
return list(zip(*arr[::-1]))
def check(board, M, N):
for i in range(N):
for j in range(N):
if board[M+i][M+j] != 1:
return False;
return True
def solution(key, lock):
M, N = len(key), len(lock)
board = [[0] * (M*2 + N) for _ in range(M*2 + N)]
# 자물쇠 중앙 배치
for i in range(N):
for j in range(N):
board[M+i][M+j] = lock[i][j]
rotated_key = key
# 모든 방향 (4번 루프)
for _ in range(4):
rotated_key = rotate90(rotated_key)
for x in range(1, M+N):
for y in range(1, M+N):
# 열쇠 넣어보기
attach(x, y, M, rotated_key, board)
# lock 가능 check
if(check(board, M, N)):
return True
# 열쇠 빼기
detach(x, y, M, rotated_key, board)
return False
https://programmers.co.kr/learn/courses/30/lessons/60062
from itertools import permutations
def solution(n, weak, dist):
L = len(weak)
cand = []
weak_point = weak + [w+n for w in weak] # 선형으로
for i, start in enumerate(weak):
for friends in permutations(dist): # 순열 이용
count = 1
position = start
# 친구 조합 배치
for friend in friends:
position += friend
# 끝 포인트까지 도달 못했을 때
if position < weak_point[i+L-1]:
count += 1 # 친구 더 투입
# 현재 위치보다 멀리 있는 취약지점 중 가장 가까운 위치로
position = [w for w in weak_point[i+1:i+L]
if w > position][0]
else: # 끝 포인트까지 도달
cand.append(count)
break
return min(cand) if cand else -1
사실 이 중 일부 문제들은 아직도 이해가 안가는 부분들이 있다.. 문자열 압축 문제와 치킨 문제만 그나마 제일 이해한듯,,!! 다행인지,, 불행인지,,,, 문제 자체가 이해가 잘 안가기도 하고, 정답 코드를 봐도 아직 알고리즘 문제에 서툴러 이해하기 쉽지 않다.. 다음주에는 좀 더 열심히 해야겠다!
안녕하세요, 김덕우입니다! 이번주 저도 너무 어려웠던 것 같아요. 구현이 원래 어려운 파트인지..
더 쉬운 문제를 풀거나 문제수를 줄여야 할지 고민이 되네요. 이번주도 너무 수고하셨습니다! 다음주도 화이팅이에요!!