diff --git a/boj/Random Defense/1475_chanbeen.py b/boj/Random Defense/1475_chanbeen.py new file mode 100644 index 0000000..079dd8b --- /dev/null +++ b/boj/Random Defense/1475_chanbeen.py @@ -0,0 +1,23 @@ +#약 20분 소요 + +num_list = list(input()) + +num_dict = {} + +for i in range(10): + num_dict[i] = 0 + +for i in range(len(num_list)): + num_dict[int(num_list[i])] += 1 + +bigger = 6 if num_dict[6] > num_dict[9] else 9 +smaller = 6 if num_dict[6] < num_dict[9] else 9 + +reuse = (num_dict[bigger] - num_dict[smaller]) // 2 +num_dict[bigger] -= reuse +num_dict[smaller] += reuse + +print(sorted(num_dict.values())[-1]) + +#입력 제한 100만 : O(n^2) 알고리즘 불가능 +#숫자별 개수 딕셔너리에서 카운팅하고, 6과 9 중 더 큰 숫자의 여유분 나눠준 뒤 가장 큰 value return \ No newline at end of file diff --git a/boj/Random Defense/1535_chanbeen.py b/boj/Random Defense/1535_chanbeen.py new file mode 100644 index 0000000..ea782eb --- /dev/null +++ b/boj/Random Defense/1535_chanbeen.py @@ -0,0 +1,23 @@ +#90분 +@, 구글링 + +N = int(input()) +life = list(map(int, input().split())) +joy = list(map(int, input().split())) + +life = [0] + life +joy = [0] + joy + +dp = [[0] * 101 for _ in range(N + 1)] + +for i in range(1, N + 1): #각 사람 순회 + for j in range(1, 101): #각 체력 순회 + if j - life[i] > 0: #이 사람 만나기 가능, joy 최댓값 갱신 + dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - life[i]] + joy[i]) + else: #현재 체력에 이 사람 만나기 불가능 + dp[i][j] = dp[i - 1][j] + +print(dp[-1][-1]) + +#그리디인줄 알았으나, 해결 안 되는 케이스 존재 +#DP로 접근 +#행은 각 사람, 열은 각 체력에서 얻을 수 있는 기쁨 \ No newline at end of file diff --git a/boj/Random Defense/1743_chanbeen.py b/boj/Random Defense/1743_chanbeen.py new file mode 100644 index 0000000..95e43f9 --- /dev/null +++ b/boj/Random Defense/1743_chanbeen.py @@ -0,0 +1,51 @@ +#약 15분 소요 + +from collections import deque + +def bfs(a, b): + visited[a][b] = True + + queue = deque([[a, b]]) + + cnt = 1 + + while queue: + x, y = queue.popleft() + + for i in range(4): + nx = x + dx[i] + ny = y + dy[i] + + if 0 <= nx < N and 0 <= ny < M: + if not visited[nx][ny]: + if array[nx][ny] == '#': + visited[nx][ny] = True + cnt += 1 + queue.append([nx, ny]) + + results.append(cnt) #뭉쳐진 쓰레기의 크기 + +N, M, K = map(int, input().split()) + +array = [['.'] * M for _ in range(N)] + +visited = [[False] * M for _ in range(N)] + +dx = [-1, 1, 0, 0] +dy = [0, 0, -1, 1] + +for _ in range(K): + r, c = map(int, input().split()) + + array[r - 1][c - 1] = '#' #쓰레기 좌표 + +results = [] + +for i in range(N): + for j in range(M): + if not visited[i][j] and array[i][j] == '#': + bfs(i, j) + +print(max(results)) + +#가장 큰 크기를 구하는 클래식한 그래프 순회 문제 \ No newline at end of file diff --git a/boj/Random Defense/17615_chanbeen.py b/boj/Random Defense/17615_chanbeen.py new file mode 100644 index 0000000..d468a34 --- /dev/null +++ b/boj/Random Defense/17615_chanbeen.py @@ -0,0 +1,69 @@ +#약 70분 소요, 15 ~ 17번째 줄 로직 구글링 + +N = int(input()) + +bs = list(input().rstrip()) + +answer = [] + +red = 0 +blue = 0 +cnt = 0 + +for i in range(N): #우측으로 빨간 공 보내기 + if bs[i] == 'R': + red += 1 + + if bs[i] == 'B' and red: #연속이 끊겼을 때만 갱신 + cnt += red #연속된 빨간 공 그룹은 안 더해지는 전략 + red = 0 + +answer.append(cnt) + +cnt = 0 + +for i in range(N): #우측으로 파란 공 보내기 + if bs[i] == 'B': + blue += 1 + + if bs[i] == 'R' and blue: + cnt += blue + blue = 0 + +answer.append(cnt) + +bs.reverse() #좌측으로 공 보내기 + +cnt = 0 +red = 0 +blue = 0 + +for i in range(N): + if bs[i] == 'R': + red += 1 + + if bs[i] == 'B' and red: + cnt += red + red = 0 + +answer.append(cnt) + +cnt = 0 + +for i in range(N): + if bs[i] == 'B': + blue += 1 + + if bs[i] == 'R' and blue: + cnt += blue + blue = 0 + +answer.append(cnt) + +print(min(answer)) + +#R 또는 B 둘 중 하나만 움직여서 같은 색깔끼리 모을 수 있는 최소 횟수 +#1. R 다 왼쪽으로 보내기 +#2. R 다 오른쪽으로 보내기 +#3. B 다 왼쪽으로 보내기 +#4. B 다 오른쪽으로 보내기 \ No newline at end of file diff --git a/boj/Random Defense/22251_chanbeen.py b/boj/Random Defense/22251_chanbeen.py new file mode 100644 index 0000000..7e6c097 --- /dev/null +++ b/boj/Random Defense/22251_chanbeen.py @@ -0,0 +1,58 @@ +#90분 +@, 구글링 + +def dfs(depth, cnt, cx): + if depth >= len(cx): #깊이 계산 변수, return 위한 base case + if int(cx) == X: #현재 층과 같으면 계산 필요 X + return 0 + elif 1 <= int(cx) <= N: #가능한 경우의 수 + return 1 + else: + return 0 + + result = 0 #가능한 경우의 수 카운팅 + cur = int(cx[depth]) #현재 바꿔줄 숫자 + + for i in range(10): + if cur != i and arr[cur][i] <= cnt: #반전 필요 & 반전 가능 횟수 내에 반전 가능 + dx = cx[:depth] + str(i) + cx[depth + 1:] #depth 위치를 i 숫자로 반전 + result += dfs(depth + 1, cnt - arr[cur][i], dx) #반전 횟수만큼 cnt 차감, 반전된 숫자로 재귀 호출 + elif cur == i: + result += dfs(depth + 1, cnt, cx) #같으면 반전 필요 X, 재귀 호출 + + return result + +N, K, P, X = map(int, input().split()) + +if len(str(X)) < K: #X가 K자리가 아닐 경우, 앞 부분은 0으로 표시 위한 작업 + cx = '0' * (K - len(str(X))) + str(X) +else: + cx = str(X) + +num = ['1111110', '0110000', '1101101', '1111001', '0110011', '1011011', + '1011111', '1110000', '1111111', '1111011'] + +arr = [] #i에서 j로 반전하는 데 필요한 횟수 저장하는 2차원 행렬 + +for i in range(10): #i에서 j로 바꿀 때 디지털 반전 횟수 계산 + arr.append([]) + + for j in range(10): + if i == j: + arr[i].append(0) #같은 숫자끼리는 반전 횟수 0 + else: + d = 0 + + for h in range(7): #0~9 숫자의 디지털 순회 + if num[i][h] != num[j][h]: #다르면, 반전 필요 + d += 1 + + arr[i].append(d) + +print(dfs(0, P, cx)) + +#N이 K자리보다 작다면 빈 공간은 0으로 채우기 +#숫자 i에서 j로 반전시키는 데 필요한 횟수를 다 저장해놔야하는데.. -> 2차원 행렬 이용 +#0~9의 숫자를 디지털로 표현하기 위한 변수 선언, 각 디지털은 각 인덱스와 매핑됨 +#이후 dfs 호출, 각 인덱스마다 반전 해야하는지, 반전하면 횟수는 얼마나 필요한지 계산 후 재귀 호출 + +#구글링해도 이해하는 데 너무 오래걸렸다. num 변수부터 해서 생각해내기 쉽지 않았던 문제 \ No newline at end of file