Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions boj/Random Defense/1475_chanbeen.py
Original file line number Diff line number Diff line change
@@ -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
23 changes: 23 additions & 0 deletions boj/Random Defense/1535_chanbeen.py
Original file line number Diff line number Diff line change
@@ -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로 접근
#행은 각 사람, 열은 각 체력에서 얻을 수 있는 기쁨
51 changes: 51 additions & 0 deletions boj/Random Defense/1743_chanbeen.py
Original file line number Diff line number Diff line change
@@ -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))

#가장 큰 크기를 구하는 클래식한 그래프 순회 문제
69 changes: 69 additions & 0 deletions boj/Random Defense/17615_chanbeen.py
Original file line number Diff line number Diff line change
@@ -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 다 오른쪽으로 보내기
58 changes: 58 additions & 0 deletions boj/Random Defense/22251_chanbeen.py
Original file line number Diff line number Diff line change
@@ -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 변수부터 해서 생각해내기 쉽지 않았던 문제