- 실제 시간에 맞춰 푼 문제
[0] 붕대감기 (100.0/100.0)
- 시간 제한 없이 풀어서 푼 문제
-
- 풀었든 못풀었든 해당 문제 어떻게 접근했는지
[O] 석유시추
[O] 아날로그 시계
[X] 수레 움직이기
접근방식
- 게임의 시간만큼 반복문을 돌림
# attackList = [[1, 2], [3, 2]] gameTime = max(attackList) + 1 # 2번 반복
- 공격시간과 피해량 배열을 각각 만든다.
# attackList = [[1, 2], [3, 2]] /* attackList = [1, 3] # 공격시간 attackHealthList = [3, 2] # 피해량 */ attackList = list((i[0] for i in attacks)) attackHealthList = list((i[1] for i in attacks))
- 답변값을 초기체력으로 초기화
answer = health
- 게임의 지속시간동안 반복하고, 체력이 0보다 같거나 작아질 경우 return -1
accumTime = 0 # 붕대감기 연속 성공 누적 시간 for i in range(1, gameTime): if answer <= 0: return -1 # 공격일 경우 # >> 반복문의 index가 몬스터 공격시간의 배열의 첫번째와 같다면 아래의 내용을 실행 # >>>> 현재체력 갱신, 붕대감기 연속 성공 누적 시간 초기화 if attackList[0] == i: answer -= attackHealthList[0] accumTime = 0 attackList.pop(0) attackHealthList.pop(0) # 공격이 아닐경우 # >> 붕대감기 연속 성공 누적 시간을 늘려주고, 초당피해회복력을 갱신 시킨후 # >> 현재 체력이 최대체력보다 같거나 클경우 > return 최대체력 # >> 현재 체력이 최대체력보다 작을경우 # >>>> 붕대감기 연속 성공 누적 시간에 도달했을 경우 # >>>>>> 추가피해회복력을 현재 체력에 더해주고, 최대체력 이상일경우 최대체력을 return else: accumTime += 1 answer += recoverHealth if answer >= health: answer = health if accumTime == recoverTime: answer += additionalRecoverHealth if answer >= health: answer = health accumTime = 0
구현코드
def solution(bandage, health, attacks):
answer = health
# 붕대감는 시전시간
recoverTime = bandage[0]
# 붕대감기 초당 회복량
recoverHealth = bandage[1]
# 붕대감기 연속 성공 후 얻는 회복량
additionalRecoverHealth = bandage[2]
attackList = list((i[0] for i in attacks))
attackHealthList = list((i[1] for i in attacks))
gameTime = max(attackList) + 1
accumTime = 0 # 붕대감기 연속 성공 누적 시간
for i in range(1, gameTime):
if answer <= 0: return -1
# 공격일 경우
if attackList[0] == i:
answer -= attackHealthList[0]
accumTime = 0
attackList.pop(0)
attackHealthList.pop(0)
else:
accumTime += 1
answer += recoverHealth
if answer >= health:
answer = health
if accumTime == recoverTime:
answer += additionalRecoverHealth
if answer >= health:
answer = health
accumTime = 0
return -1 if answer <= 0 else answer
소요시간
1시간 20분 (문제 이해 - 10분, 접근 방식 - 10분, 구현 - 60분)
풀이결과
놓친 조건을 잡느라 오래 걸렸고, python으로 구현하느라 평소보다 오래 걸렸다.
문제) PCCP 기출문제 2번 - 석유시추
복사한 코드
접근방식
- 석유가 뭍혀 있는 곳을 타고타고 들어가서 표시를 해야됨
def bfs(a, b): count = 0 visited[a][b] = 1 q = deque() q.append((a,b)) min_y, max_y = b, b while q: x,y = q.popleft() min_y = min(min_y, y) max_y = max(max_y, y) count += 1 for i in range(4): nx = x + dx[i] ny = y + dy[i] if nx < 0 or ny < 0 or nx >= n or ny >= m: continue if visited[nx][ny] == 0 and land[nx][ny] == 1: visited[nx][ny] = 1 q.append((nx,ny))
- 시추관을 설치한 위치(column)에 따라 뽑을 수 있는 석유에 대한 배열을 만든다.
for i in range(n): for j in range(m): if visited[i][j] == 0 and land[i][j] == 1: bfs(i,j)
구현코드
from collections import deque
def solution(land):
answer = 0
n = len(land)
m = len(land[0])
dx = [0,0,1,-1]
dy = [1,-1,0,0]
result = [0 for i in range(m+1)]
visited = [[0 for i in range(m)] for j in range(n)]
def bfs(a, b):
count = 0
visited[a][b] = 1
q = deque()
q.append((a,b))
min_y, max_y = b, b
while q:
x,y = q.popleft()
min_y = min(min_y, y)
max_y = max(max_y, y)
count += 1
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx < 0 or ny < 0 or nx >= n or ny >= m:
continue
if visited[nx][ny] == 0 and land[nx][ny] == 1:
visited[nx][ny] = 1
q.append((nx,ny))
for i in range(min_y, max_y+1):
result[i] += count
for i in range(n):
for j in range(m):
if visited[i][j] == 0 and land[i][j] == 1:
bfs(i,j)
answer = max(result)
return answer
풀이결과
못품.. (문제 이해 - 5분, 접근 방식 - 10분, 구현 - X)
풀이결과
문제 이해와 접근방식은 파악했지만, BFS구조나 구현에 대한 이해가 부족해 구현하지 못하였다.
문제) PCCP 기출문제 3번 - 아날로그 시계
복사한 코드
접근방식
- 분침과 초침이 만날때만 count하면 되는 것이기때문에, 1초에 분침이 움직이는 각도와, 초침이 움직이는 각도를 구해야 함.
- 주어진 시작시각과 끝시각을 초단위로 변환해야 함.
- 주어진 시작시각과 끝시각 동안 분침과 초침이 이동한 각도를 계산해야함
구현코드
def solution(h1, m1, s1, h2, m2, s2):
answer = 0
# 시작시간과 끝시간을 초단위로 변환
startTime = h1 * 3600 + m1 * 60 + s1
endTime = h2 * 3600 + m2 * 60 + s2
# next기준으로 계산할거니 포함되지 않는 시작시간 00시, 12시 미리 카운팅
if startTime == 0 * 3600 or startTime == 12 * 3600:
answer += 1
while startTime < endTime:
# 시침 1시간 = 30도 -> 1초에 30/3600도 즉, 1/120도 이동
# 분침 1분 = 6도 -> 1초에 6/60도 즉, 1/10도 이동
# 초침 1초 = 6도 -> 1초에 6도 이동
hCurAngle = startTime / 120 % 360
mCurAngle = startTime / 10 % 360
sCurAngle = startTime * 6 % 360
# 다음 위치가 360도가 아닌 0도로 계산되어 카운팅에 포함되지 않는 경우 방지
# 이동했을 때 지나쳤거나 같아졌는지를 비교하는 것이므로 현재위치는 해줄 필요없음
hNextAngle = 360 if (startTime + 1) / 120 % 360 == 0 else (startTime + 1) / 120 % 360
mNextAngle = 360 if (startTime + 1) / 10 % 360 == 0 else (startTime + 1) / 10 % 360
sNextAngle = 360 if (startTime + 1) * 6 % 360 == 0 else (startTime + 1) * 6 % 360
if sCurAngle < hCurAngle and sNextAngle >= hNextAngle:
answer += 1
if sCurAngle < mCurAngle and sNextAngle >= mNextAngle:
answer += 1
# 시침/분침과 동시에 겹쳤을 때 중복카운팅 제외
if sNextAngle == hNextAngle and hNextAngle == mNextAngle:
answer -= 1
startTime += 1
return answer
소요시간
풀지 못함. (문제 이해 - 3분, 접근 방식 - 10분, 구현 - X)
풀이결과
중고등학교때 많이 나오는 문제라서 풀 수 있겠다 생각했다. (결론: 못품)
시간이 나오면 포맷팅을 어떻게 해야하는 지 머리가 하얘진다.
그래도 접근방식은 빨리 도달해서 다행이긴 했다.
문제) PCCP 기출문제 4번 - 수레 움직이기
참고링크 - C++
접근방식
구현코드
소요시간
풀지 못함. (문제 이해 - 10분, 접근 방식 - X, 구현 - X)
풀이결과
(추가예정)