diff --git "a/Hongjoo/\353\260\261\354\244\200/\353\263\221\353\223\240\353\202\230\354\235\264\355\212\270.py" "b/Hongjoo/\353\260\261\354\244\200/\353\263\221\353\223\240\353\202\230\354\235\264\355\212\270.py" new file mode 100644 index 00000000..c5f86290 --- /dev/null +++ "b/Hongjoo/\353\260\261\354\244\200/\353\263\221\353\223\240\353\202\230\354\235\264\355\212\270.py" @@ -0,0 +1,38 @@ +""" +실버3 +https://www.acmicpc.net/problem/1783 + +#문제 : 그래프탐색(DFS , BFS) +- NxM 의 왼쪽 아래 칸 시작 +- 4가지 방법으로 이동 + (1) 2칸 위 , 1칸 오른쪽 + (2) 1칸 위로 2칸 오른쪽 + (3) 1칸 아래로 , 2칸 오른쪽 + (4) 2칸 아래 , 1칸 오느ㅜㄹ쪽 +- goal) 방문할 수 있는 "최대 칸 개수" 구하기 + +# 조건 +- <이동횟수가 4번 이상 -> 이동 방법 모두 사용 +- < 4번 이하 - 제약 없음 + + +""" +n, m = map(int, input().split()) + +result = 0 +# n이 1일 때 무조건 1 +if n == 1: + result = 1 +# n이 2일 때 +elif n == 2: + if m >= 1 and m <= 6: #m이 1~6일 때 + result = (m + 1) // 2 + elif m >= 7: #7이상일 때 + result = 4 +# n이 3 이상일 때 +elif n >= 3: + if m <= 6: #m이 1~6일 때 + result = min(m, 4) + elif m >= 7: #m이 7 이상일 때 + result = m - 2 +print(result) diff --git "a/Hongjoo/\353\260\261\354\244\200/\354\211\254\354\232\264\352\263\204\353\213\250\354\210\230.py" "b/Hongjoo/\353\260\261\354\244\200/\354\211\254\354\232\264\352\263\204\353\213\250\354\210\230.py" new file mode 100644 index 00000000..66e5a61e --- /dev/null +++ "b/Hongjoo/\353\260\261\354\244\200/\354\211\254\354\232\264\352\263\204\353\213\250\354\210\230.py" @@ -0,0 +1,25 @@ +""" +https://www.acmicpc.net/problem/10844 +""" +n = int(input()) +# dp [총 길이 i ][마지막 자리수가 j] = 인 개수 +Mod = 1000000000 +# 1. 초기화 +#(1) 0을 시작하는 수는 계단수가 아닌다 - dp[1][0] +# (2) N=1 인 계단수 +dp = [[0]*10 for _ in range(n+1)] +dp[1][0] = 0 +for j in range(1,10): + dp[1][j]= 1 + +# (3) 점화식 N>=2 +for i in range(2,n+1): + for j in range(10): + if j== 0 : + dp[i][j] = dp[i-1][j+1] + elif j==9: + dp[i][j] = dp[i-1][j-1] + else : + dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1] + +print(sum(dp[n])%Mod) \ No newline at end of file diff --git "a/Hongjoo/\353\260\261\354\244\200/\354\240\200\354\232\270.py" "b/Hongjoo/\353\260\261\354\244\200/\354\240\200\354\232\270.py" new file mode 100644 index 00000000..a30d8861 --- /dev/null +++ "b/Hongjoo/\353\260\261\354\244\200/\354\240\200\354\232\270.py" @@ -0,0 +1,20 @@ +""" +https://www.acmicpc.net/problem/2437 + +# 문제 +- 저울 N개의 조합의 합으로 구현할 수 없는 양의 최소값 구하기 +- N<=1000개 +- 1개 무게 >= 1,000,0000 +유형 : 그리디 , 정렬 + +""" +#1. 입력 저울추 & 오름차순 정렬 +N = int(input()) +weights = sorted(list(map(int, input().split()))) +target = 1 +for w in weights : + if target < w : + break + + target += w +print(target) diff --git "a/Hongjoo/\353\260\261\354\244\200/\355\225\234\352\265\255\354\235\264\352\267\270\353\246\254\354\232\270\353\225\220\354\204\234\353\262\204\354\227\220\354\240\221\354\206\215\355\225\230\354\247\200.py" "b/Hongjoo/\353\260\261\354\244\200/\355\225\234\352\265\255\354\235\264\352\267\270\353\246\254\354\232\270\353\225\220\354\204\234\353\262\204\354\227\220\354\240\221\354\206\215\355\225\230\354\247\200.py" new file mode 100644 index 00000000..b2941e9f --- /dev/null +++ "b/Hongjoo/\353\260\261\354\244\200/\355\225\234\352\265\255\354\235\264\352\267\270\353\246\254\354\232\270\353\225\220\354\204\234\353\262\204\354\227\220\354\240\221\354\206\215\355\225\230\354\247\200.py" @@ -0,0 +1,34 @@ +""" +https://www.acmicpc.net/problem/9996 +""" +N = int(input()) +# Q. a*b는 asbasd도 정답인가? +# 1. 변수 입력 받기 +pattern = list(input().split('*')) +cmstr = [[] for k in range(N)] + +for i in range(N): + # cmstr[i] = [x for x in input()] + cmstr[i] = input() +#2. + +for i in range(N): + # 패턴 앞, 뒤 매칭하기 + if cmstr[i][:len(pattern[0])] != pattern[0] or cmstr[i][-len(pattern[-1]):] != pattern[-1]: + print("NE") + continue + # 안 맞음 + + flag = [False * len(pattern[1:-1])] + point = len(pattern[0]) + for p in pattern[1:-1] : # 패턴 내부 + cnt = cmstr[i][point:].find(p) + if cnt < 0 : #없으면 + print("NE") + break + # 있으면 - 그 이전에 있음 + point = cnt + + print("DA") + + diff --git "a/Hongjoo/\354\275\224\353\223\234\355\212\270\353\246\254/\352\263\240\353\214\200\353\254\270\353\252\205\354\234\240\354\240\201\355\203\220\354\202\254.py" "b/Hongjoo/\354\275\224\353\223\234\355\212\270\353\246\254/\352\263\240\353\214\200\353\254\270\353\252\205\354\234\240\354\240\201\355\203\220\354\202\254.py" new file mode 100644 index 00000000..89918f0d --- /dev/null +++ "b/Hongjoo/\354\275\224\353\223\234\355\212\270\353\246\254/\352\263\240\353\214\200\353\254\270\353\252\205\354\234\240\354\240\201\355\203\220\354\202\254.py" @@ -0,0 +1,150 @@ +""" +#2024삼성 상반기 오전1번 문제 / 고대문명유적탐사 +#링크 : https://www.codetree.ai/ko/frequent-problems/problems/ancient-ruin-exploration/description?introductionSetId=&bookmarkId= + + +""" +""" +# 유형 : 걍 구현 +- . 5x5위 7가지 유물(1-7) +1. 탐사 진행 - 지정된 3x3회전 시계방향으로 [90,180 , 270] 중 하나의 각도로 회전 + => 각 회전시 "각도| 획득가치 | 중심좌표" 저장 + - (1) 유물 1차 획득 가치 최대화 + - (2) 회전 각도 최소화 + - (3) 회전 중심 좌표 열(row)이 최소 -> 행 최소 + + +2. 유물 획득 +- 3개 같은 종류 이웃하면 -> 사라지는 조각 개수 = 유물 가지 => 필트에 빔 +- 생성 순서는 유적 벽면 순서 -> 열이 작은 쪽 -> & 행 큰것 순서 up +- 조각 고갈 문제는 없음, 단 사용한 조각은 재활용 x > + +3. 탐사 반복 (출력조건) +- K번 (1번 : 탐사진행 -> 유물획득) => 획득 유물 가치 출력 +- 중간 획득 유물 방법 존재 x -> 종료 (출력 : x ) + +""" + +""" +<전체 flow> +# 0. 변수 입력 : 탐사 회수 K , 유물 스페어 개수 M +### K 번 반복 +# 중심좌표 후보군 9개 / 각도 후보군 3개 -> 27번 반복 +#1. def 회전(중심좌표, 각도) + +#2. 유물 획득 -> 유물 가치 저장 +#-> 27번 반복 +#3. 해당 턴에서 Best choice 인 상황 결정 +# 3.유물 업데이트 +### +""" +""" +input : 중심 좌표, angle , field +ouptut : 변환된 field + +위치 idx : +[[i-1 , j-1], [i-1, j],[i-1,j+1],[i+1,j-1] , [i,j] [ i,j+1], [i+1,j-1],[i+1,j],[i+1,j+1]] +90 = [7,5,1,8,5,2,9,6,3] +80 = [7,8,9,4,5,6,1,2,3] +270 = [1,4,7,2,5,8,3,6,9] +""" +""" +# 유물 획득 함수 : BFS +# 현 field 상황에서 얻을 수 있는 경우의 수 +def get_old (field): +""" + +# 중심 좌표 후보군 + +# 0. 입력 변수 입력 받기 +K , M = map(int, input().split()) +# 0-1. 초기 필드 값 받기 + +sfield = [list(map(int,input().split())) for _ in range(5) ] +wall = list(map(int, input().split())) +# 상하좌우 +dy = [-1,1,0,0] +dx = [0,0,-1,1] + + +# (1) 90/180/270 회전 함수 +def rotate(i,j, angle ,field) : + old_33=[[i-1 , j-1], [i-1, j],[i-1,j+1],[i+1,j-1] , [i,j] ,[ i,j+1], [i+1,j-1],[i+1,j],[i+1,j+1]] + ro_pos =[] + if angle == "90": + ro_pos = [6,4,0,7,4,1,8,5,2] + elif angle == "180": + ro_pos = [6,7,8,3,4,5,0,1,2] + else: + ro_pos = [0,3,6,1,4,7,2,5,8] + new_field = [row[:] for row in field] + for p in range(0,9): + + old = field[old_33[p][0]][old_33[p][1]] + new_field[old_33[ro_pos.index(p)][0]][old_33[ro_pos.index(p)][1]] = old + return field + +# 현 field 상황에서 가치 업데이트 +def get_old (field): + del_pos = [] + visited = [] # 방문 여부 + oldest = [] # 각 start point에서 연결된 유물 위치 + for i in range(5): + for j in range(5): + if [i,j] not in visited : + # start point와 같은 종류의 유물만 획득 가능 + q = [] + q.append([i,j]) + visited.append([i,j]) + while q : + cy,cx = q.pop() + for d in range(4) : + ny , nx = cy + dy[d] , cx + dx[d] + if 0 <= ny < 5 and 0 <= nx < 5 : + if [ny,nx] not in visited and field[ny][nx] == field[cy][cx]: + q.append([ny,nx]) + visited.append([ny,nx]) + oldest.append([ny,nx]) + + # 획득 있으면 -> 유물 개수 + 위치 누적 + if len(oldest) >= 3 : # 3개 이상 연결시 획득 가능 + del_pos.extend(oldest) + # print(del_pos) + oldest.clear() + + return len(del_pos) , del_pos +# best 상황 선택 +def cur_best(current_case): + arr = sorted(current_case , key=lambda x : (-x[0] , x[1] , x[2], x[3])) + return arr[0] + + +answer = [] + +for k in range(K): + current_case = [] # 27경우 [유물가지, 각도 , 열, 행 ,삭제 위치 ] + # 9개의 중심좌표 후보군 + ro_sub = [90,180,270] + center_sub= [[1,1], [1,2],[1,3],[2,1] ,[2,2] ,[2,3],[3,1],[3,2],[3,3]] + for center_y , center_x in center_sub : + for ro_angle in ro_sub : + sub_field = rotate(center_y,center_x, ro_angle ,sfield) + value_sub , del_sub = get_old (sub_field) + current_case.append([value_sub, ro_angle, center_y, center_x, sub_field ,del_sub]) + + #3. 해당 턴에서 베스트 상황 1개 선택 + # value 가 없는 경우 -> 끝 + if len(current_case) <= 0 : + break + best_sit=cur_best(current_case) + answer.append(best_sit[0]) + #4. fiedl 상황 업데이트 + # 유물 매꾸기 - sort로 삭제된 위치 정렬 후 wall(유물벽면) 수행 + arr = sorted(best_sit[-1] , key = lambda x : (x[0] , -x[1])) # 사라진 유물 위치 + sfield = best_sit[-2] + pointer = 0 + for y,x in arr : + node = wall[pointer] + sfield[y][x] = node + pointer= (pointer+1)%len(wall) + +print(answer) \ No newline at end of file diff --git "a/Hongjoo/\354\275\224\353\223\234\355\212\270\353\246\254/\353\251\224\353\221\220\354\202\254\354\231\200\354\240\204\354\202\254\353\223\244.py" "b/Hongjoo/\354\275\224\353\223\234\355\212\270\353\246\254/\353\251\224\353\221\220\354\202\254\354\231\200\354\240\204\354\202\254\353\223\244.py" new file mode 100644 index 00000000..07de28ae --- /dev/null +++ "b/Hongjoo/\354\275\224\353\223\234\355\212\270\353\246\254/\353\251\224\353\221\220\354\202\254\354\231\200\354\240\204\354\202\254\353\223\244.py" @@ -0,0 +1,206 @@ +""" +BFS , 구현 , 시뮬레이션 +""" +#상 o, 우상, 우, 우하 , 하, 좌하, 좌, 좌상 +di = [-1,-1,0,1,1,1,0,-1] +dj = [0,1,1,1,0,-1,-1,-1] +#디버깅 용 +def myprint(arr): + for lst in arr: + print(*lst) # 2행 리시트는 1열이 1 instacne + print() + +# [0] BFS 로 메듀사 최단경로 : 도로 따라 공원까지 - 상하좌우 +# route = find_route(si,sj,ei,ej) +from collections import deque +def find_route(si,sj,ei,ej): + q = deque() + v = [ [0]*N for _ in range(N)] # 방문 여부 & *직전 위치* + + q.append((si,sj)) + v[si][sj] = (si,sj) # 직전 위치 저장 + + while q : + ci, cj = q.popleft() + + # 목적지 도착 -> 경로 저장 + if (ci,cj)==(ei,ej) : + + route = [] + ci,cj = v[ci][cj] + while (ci,cj) !=(si,sj): # 출발지가 아니면 저장 + route.append((ci,cj)) + ci,cj = v[ci][cj] + return route[::-1] #역순(메듀사 이동 start- > end 순서대로) + + # 4방향(상하좌우), 범위내 , 미방문 ,조건(==0) + for di,dj in ((-1,0),(1,0),(0,-1),(0,1)): + ni, nj = ci+di , cj+ dj + if 0<= ni 1 "w ~2" + + while 0<= ci< N and 0 <= cj>>tv , tston + +def make_stone (marr, mi,mj,dr): + v = [[0]*N for _ in range(N)] + cnt = 0 # stone된 병사 개수 + +# myprint(marr) + #[1] dr 방향으로 w(>0) 만날때 까지 1 표시 , 이후 2 표시 + ni, nj = mi + di[dr] , mj+dj[dr] + + while 0<=ni 0 : # 병사 w 만남 + cnt+=marr[ni][nj] # 해당 영역의 모든 w 석화 + ni, nj = ni + di[dr] , nj+dj[dr] # 다음 칸으로 이동 + + mark_line(v,ni,nj,dr) # v에 dr 방향으로 이동 가능 지역 표시 + + break + ni, nj = ni + di[dr] , nj+dj[dr] + #[2] dr -1 ,dr +1 방향으로 M의 시선 동일 처리, 대각선 원점 잡고 dr 방향으로 처리 + for org_dr in ((dr-1)%8 , (dr+1)%8): + si,sj = mi+di[org_dr], mj+dj[org_dr] # 첫 대각선 위치부터 체크 + + # 대각선 시야각 영역 확인 + while 0<=si 0: # 전사 만남 + v[si][sj] = 1 + cnt += marr[si][sj] + mark_safe(v,si,sj,dr,org_dr) # 전사가 바라보는 방향으로 safe(이동 가능 범위) 표시 + break + # W 가 길 중간에 있는 경우 + ci ,cj = si,sj # 첫 위치가 전사가 아닐 경우는 직선으로 + while 0 <= ci 0 : # 전사로 막히면 + cnt+= marr[ci][cj] + mark_safe(v, ci,cj,dr,org_dr) # v에서 dr 방향으로 이동 가능 지역 표시 + break + else : + break + ci,cj = ci+di[dr], cj+dj[dr] + + si,sj = si+di[org_dr], sj+dj[org_dr] + return v, cnt + +# move_cnt , attk_cnt = move_men(v,mi,mj) + +def move_men(v,mi,mj) : + # [3] 전사의 이동 - (상하좌우)(좌우상하) 메두사 시야 아니면 (!=1) + move , attk = 0,0 + for dirs in (((-1,0),(1,0),(0,-1),(0,1)), ((0,-1),(0,1),(-1,0),(1,0))): + for idx in range(len(men)-1,-1,-1): + ci ,cj = men[idx] + if v[ci][cj] == 1 : # 메듀사 시야 내에 있으면 -> 정지 + continue + dist = abs(mi-ci) +abs(mj-cj) # 현재 거리 + for di,dj in dirs : + ni,nj = ci +di ,cj +dj # w 의 다음 이동 공간 + #범위내 메듀사 시야 아니고, 현재 거리보다 더 줄어드는 방향 (상하좌우 우선순위로 이동) + if 0<=niabs(mi-ni)+abs(mj-nj): + if (ni,nj) == (mi,mj): # 공격 -> 죽음 + attk+=1 + men.pop(idx) + else : + men[idx] = [ni,nj] + move += 1 + break + return move, attk + +############### +# main FLOW +############### + + +# 0. 입력 +# 마을 크기 M , 전산수 N / 메듀사 위치정보s , 공원 위치 정보 e / M명 전사 좌표 N/ 개의 도로 정보 +N , M = map(int, input().split()) +si , sj , ei , ej = map(int , input().split()) +tlist = list(map(int , input().split())) + +# 전사 좌표 +men = [] +for i in range(0, M*2 , 2) : + men.append([tlist[i], tlist[i+1]]) +# 필드 정보 +arr =[list(map(int, input().split())) for _ in range(N)] + + + +# [0] BFS 로 메듀사 최단경로 : 도로 따라 공원까지 - 상하좌우 + +route = find_route(si,sj,ei,ej) + + + +if route == -1 : # 길이 없는 경우 + print(-1) +else : + for mi,mj in route : # 각 time = idx 별 메듀사 위치 + move_cnt , attk_cnt = 0, 0 + # [1]메듀사의 이동 : 지정된 최단거리로 한칸 이동 (전사와 만날 경우 , 전사 삭제) + + for i in range(len(men)-1,-1,-1) : # 역순 탐색 + if men[i] == [mi,mj] : + men.pop(i) + + #[2] 메듀사 시선 : 상하좌우 방향중 "가장 많이 stone 되는 방향" 선택 + # v[] : 메듀사의 시선 명시해서 이동시 참조(메듀사시선 =1 , 전사에게 가려진 곳 ==2 ,빈땅 ==0) + # mar[][] : 지도에 있는 현재 전사 수 (및 위치) 표시(중복 존재 가능) + marr = [[0]*N for _ in range(N)] + for ti, tj in men : + marr[ti][tj] += 1 + + + max_stone = -1 # 4 방위 중 max stoning 가능한 개수 + v= [] #현 필드내 메듀사 시선으로 생기는 영억 속성 설정 + + # 4방위 바교 + for dr in (0,4,6,2) : # 상하좌우 순서대로 처리 + tv , tstone = make_stone(marr , mi , mj, dr) + # 최대값 갱신 - max_stone 개수 & 시선 영역 속성 설정 + if max_stone < tstone : + max_stone = tstone + v = tv + + + + + #[3] 전사의 이동 (한 칸씩 두번) : 메듀사 있는 경우 공격 + # 메듀사와 가까워지는 방향으로 접근 + move_cnt , attk_cnt = move_men(v,mi,mj) + + print(move_cnt, max_stone , attk_cnt) + print(0) \ No newline at end of file diff --git "a/Hongjoo/\354\275\224\353\223\234\355\212\270\353\246\254/\353\257\270\354\247\200\354\235\230\352\263\265\352\260\204\355\203\210\354\266\234.py" "b/Hongjoo/\354\275\224\353\223\234\355\212\270\353\246\254/\353\257\270\354\247\200\354\235\230\352\263\265\352\260\204\355\203\210\354\266\234.py" new file mode 100644 index 00000000..59333103 --- /dev/null +++ "b/Hongjoo/\354\275\224\353\223\234\355\212\270\353\246\254/\353\257\270\354\247\200\354\235\230\352\263\265\352\260\204\355\203\210\354\266\234.py" @@ -0,0 +1,174 @@ +""" + + + +""" + +def myprint_3d(arr3) : + for arr in arr3: + for lst in arr: + print(*lst) + print() + print() + +def myprint_2d(arr): + for lst in arr: + print(*lst) + print() + +# sk_3d ,si_3d, sj_3d = find_3d_start() +def find_3d_start(): # 3d 출발 지점 좌표 + for i in range(M) : + for j in range(M) : + if arr3[4][i][j]==2 : + return 4, i, j + +def find_2d_end(): # 2d에서 최종 도착 지점 + for i in range(N): + for j in range(N) : + if arr[i][j] == 4 : + arr[i][j] = 0 + return i , j + +def find_3d_base(): # 전체 맵에서 3d 영역 시작(절대)좌표 - 좌측 상단 + for i in range(N) : + for j in range(N) : + if arr[i][j] ==3 : + return i, j + +# 3d 차원 & 2d 시작 위치 (텔레포트) 좌표 반환 +# 3d : 상대 좌표 -> 2d 전체 맵 절대 좌표 +def find_3d_end_2d_start(): + #[1] 3차원 시작 좌표(base) 찾기 =3 등장 -> 좌측상단 + bi , bj = find_3d_base() + + #[2] 3차원 좌표에서 2d 차원 연결 좌표 찾기 (1차 목적지 in 3d ) + # i,j : 2d 전체 맵 기준 + # si ,sj = 2d통로 = 3d 통로 : (ek,ei,ej) + for i in range(bi , bi+M) : + for j in range(bj, bj+M) : + if arr[i][j]!=3 : # 3차원 위치 아니면 skip + continue + + # 1차 출구 : 3d 차원에서 ->2d 로 텔레포트 하는 위치 + if arr[i][j+1] == 0 : # 우측에 3d - 2d 탈출구 (3차원 우측으로 1차 출구) + return 0 , M-1 , (M-1)-(i-bi) , i, j+1 # ek(평면) = 0 동쪽 , ei = M-1 , ej = i , si = i , sj = j+1 + elif arr[i][j-1] ==0 : # 좌측 1차 출구 + return 1, M-1, i-bi, i, j-1 # ek(평면)=1, ei=M-1, ej=i, si=i, sj=j+1 + elif arr[i+1][j]==0 : # 아래쪽 1차 출구 + return 2, M-1 , j-bj, i+1 ,j # ek(평면)=2, ei=M-1, ej=i, si=i, sj=j+1 + elif arr[i-1][j] == 0 : # 위쪽에 1차 출구 + return 3 ,M-1 , (M-1)-(j-bj) , i-1 , j # ek(평면)=3, ei=M-1, ej=i, si=i, sj=j+1 + #여기까지 올릴 없지만 + return -1 + +from collections import deque +# dist = bfs_3d(sk_3d ,si_3d, sj_3d ,ek_3d , ei_3d,ej_3d) + +left_nxt = {0:2, 2:1, 1:3, 3:0} +right_nxt = {0:3, 2:0, 1:2, 3:1} + +def bfs_3d(sk ,si, sj ,ek , ei,ej): + q = deque() + v = [[[0]*M for _ in range(M)] for k in range(5) ] # 방문 여부 + 최소 거리 + + q.append((sk , si, sj)) + v[sk][si][sj] = 1 + + while q : + ck ,ci , cj = q.popleft() + + # 목적지 도달 + if (ck,ci,cj) == (ek,ei, ej) : + return v[ck][ci][cj] + + + # 4방향, 범위내/ 범위 밖 -> 다른 k 로 이동 처리 , 미방문 + for di,dj in ((-1,0) ,(1,0), (0,-1), (0,1)): + ni , nj = ci+di , cj + dj + # 범위 밖으로 이동- > 다른 k 평면으로 이동 + if ni<0 : #(1) 위쪽 범위 밖 이탈 + if ck == 0 : nk , ni , nj = 4 , (M-1)-cj , M-1 + elif ck == 1 : nk,ni , nj = 4 , cj , 0 + elif ck == 2 : nk , ni, nj = 4, M-1 , cj + elif ck == 3 : nk , ni ,nj = 4,0,(M-1)-cj + elif ck == 4 : nk, ni, nj = 3 , 0 ,(M-1)-cj + elif ni >= M : #(2) 아래쪽으로 범위 이탈 + if ck == 4 : nk, ni, nj = 2, 0, cj + else : continue + elif nj < 0 : # (3) 왼쪽 범위 이탈 + if ck ==4 : nk , ni , nj = 1, 0 , ci + else : + nk, ni, nj = left_nxt[ck], ci , M-1 + elif nj >= M : # (4) 오른쪽 범위 이탈 + if ck == 4 : nk, ni, nj = 0 , 0, (M-1)-ci + else : + nk, ni, nj = right_nxt[ck] , ci, 0 + else : # (5) 범위 내 + nk = ck + # 미방문 , 조건 맞으면 + if v[nk][ni][nj] == 0 and arr3[nk][ni][nj] == 0 : + q.append((nk,ni,nj)) + v[nk][ni][nj] = v[ck][ci][cj]+1 + # 여긴 경로 없음 + return -1 +# dist = bfs_2d(v , dist ,si,sj, ei , ej ) +def bfs_2d(v , dist ,si,sj, ei , ej ): + q= deque() + + q.append((si,sj)) + v[si][sj] = dist + + while q : + ci,cj = q.popleft() + if (ci,cj) == (ei,ej): + return v[ci][cj] + # 네방향, 범위내, (미방문)/조건맞으면(길이고, v[ci][cj]+1 탈출 위치거리 탐색(BFS 최단거리) +dist = bfs_3d(sk_3d ,si_3d, sj_3d ,ek_3d , ei_3d,ej_3d) +# 동 서 남 북 +di=[ 0, 0, 1,-1] +dj=[ 1,-1, 0, 0] +if dist != -1 : # 3d 탈출 불가능 + #[3] 2차원 탐색 준비 : 시간 이상 현상 처리해서 v 에 시간 표시 : BFS 확산시 v 배수보다 작으면 통과 표시 + # value: 이상 현상이 발생하는 time + v = [[401]*N for _ in range(N)] + + for wi, wj , wd ,wv in wall : # 이상 현상 초기 위치 , 확산 방향 , 확산 상수 + v[wi][wj] = 1 + for mul in range(1, N+1) : + wi ,wj = wi+di[wd] , wj + dj[wd] # 다음 확산될 곳 + if 0<= wi wv*mul : # 더 큰값일때만 갱신(겹칠 수 있음) + v[wi][wj] = wv*mul + else : + break + + #[4] 2차원 시작 위치에서 BFS로 탈출구 탐색 + dist = bfs_2d(v , dist ,si,sj, ei , ej ) +print(dist) \ No newline at end of file diff --git "a/_WeeklyChallenges/W16-[DP]/Assignment_BOJ_1562_\352\263\204\353\213\250\354\210\230.py" "b/_WeeklyChallenges/W16-[DP]/Assignment_BOJ_1562_\352\263\204\353\213\250\354\210\230.py" new file mode 100644 index 00000000..30d3e7c9 --- /dev/null +++ "b/_WeeklyChallenges/W16-[DP]/Assignment_BOJ_1562_\352\263\204\353\213\250\354\210\230.py" @@ -0,0 +1,34 @@ +''' +BOJ #1562. 계단수 (골드 1) +https://www.acmicpc.net/problem/1562 +유형: 비트마스킹, DP +''' + +N = int(input()) +MOD = 1_000_000_000 +BIT = 1 << 10 + +dp = [[[0] * BIT for _ in range(10)] for _ in range(N)] + +for j in range(1, 10): + dp[0][j][1 << j] = 1 + +for i in range(1, N): + for j in range(10): + for bit in range(BIT): + nxt_bit = bit | 1 << j + + if 0 < j: + dp[i][j][nxt_bit] += dp[i - 1][j - 1][bit] + + if j < 9: + dp[i][j][nxt_bit] += dp[i - 1][j + 1][bit] + + dp[i][j][nxt_bit] %= MOD + +cnt = 0 +for j in range(10): + cnt += dp[N - 1][j][BIT - 1] + cnt %= MOD + +print(cnt) \ No newline at end of file diff --git a/_WeeklyChallenges/W16-[DP]/README.md b/_WeeklyChallenges/W16-[DP]/README.md new file mode 100644 index 00000000..55ede299 --- /dev/null +++ b/_WeeklyChallenges/W16-[DP]/README.md @@ -0,0 +1,16 @@ +## 🚀4월 1주차 (4/07) 스터디 발제 주제: DP +> 발제자: 김홍주 + +> 주제: DP +### 🗂️ 스터디 자료 +- PDF: [바로가기 +](./Study_BOJ_10844.pdf) + +### 📖 문제 +- [백준 #10844. 쉬운계단수](https://www.acmicpc.net/problem/10844): DP / 실버1 +- 정답 코드: [Study_BOJ_2293_10844_쉬운계단수.py](./Study_BOJ_10844_쉬운계단수.py) + + +### 💻 과제 +- [백준 #1562. 계단수](https://www.acmicpc.net/problem/1562): 비트마스킹,DP / 골드 1 +- 정답 코드: [Assignment_BOJ_1562_계단수.py](./Assignment_BOJ_1562_계단수.py) diff --git a/_WeeklyChallenges/W16-[DP]/Study_BOJ_10844.pdf b/_WeeklyChallenges/W16-[DP]/Study_BOJ_10844.pdf new file mode 100644 index 00000000..43e2fda2 Binary files /dev/null and b/_WeeklyChallenges/W16-[DP]/Study_BOJ_10844.pdf differ diff --git "a/_WeeklyChallenges/W16-[DP]/Study_BOJ_10844_\354\211\254\354\232\264\352\263\204\353\213\250\354\210\230.py" "b/_WeeklyChallenges/W16-[DP]/Study_BOJ_10844_\354\211\254\354\232\264\352\263\204\353\213\250\354\210\230.py" new file mode 100644 index 00000000..8b2c8aa4 --- /dev/null +++ "b/_WeeklyChallenges/W16-[DP]/Study_BOJ_10844_\354\211\254\354\232\264\352\263\204\353\213\250\354\210\230.py" @@ -0,0 +1,27 @@ +''' +BOJ #10844. 쉬운 계단수 (실버1) +https://www.acmicpc.net/problem/10844 +유형: DP +''' + +n = int(input()) + +Mod = 1000000000 +# 1. 초기화 +# dp [총 길이 i ][마지막 자리수가 j] = 인 개수 +dp = [[0]*10 for _ in range(n+1)] +dp[1][0] = 0 +for j in range(1,10): + dp[1][j]= 1 + +# 2 점화식 N>=2 +for i in range(2,n+1): + for j in range(10): + if j== 0 : + dp[i][j] = dp[i-1][j+1] + elif j==9: + dp[i][j] = dp[i-1][j-1] + else : + dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1] + +print(sum(dp[n])%Mod) \ No newline at end of file