[PCCP 기출문제] - Python

hiereit·2023년 12월 7일
0

코딩테스트연습

목록 보기
3/3
post-thumbnail

Summary

  1. 실제 시간에 맞춰 푼 문제
  • [0] 붕대감기 (100.0/100.0)
  1. 시간 제한 없이 풀어서 푼 문제
  • -
  1. 풀었든 못풀었든 해당 문제 어떻게 접근했는지
  • [O] 석유시추
  • [O] 아날로그 시계
  • [X] 수레 움직이기

Lv1. 붕대감기

문제) PCCP 기출문제 1번 - 붕대감기

접근방식

  1. 게임의 시간만큼 반복문을 돌림
# attackList = [[1, 2], [3, 2]]
gameTime = max(attackList) + 1 # 2번 반복
  1. 공격시간과 피해량 배열을 각각 만든다.
# 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))
  1. 답변값을 초기체력으로 초기화
answer = health
  1. 게임의 지속시간동안 반복하고, 체력이 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으로 구현하느라 평소보다 오래 걸렸다.

Lv2. 석유시추

문제) PCCP 기출문제 2번 - 석유시추
복사한 코드

BFS 이해링크1
BFS 이해링크2

접근방식

  1. 석유가 뭍혀 있는 곳을 타고타고 들어가서 표시를 해야됨
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))
  1. 시추관을 설치한 위치(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구조나 구현에 대한 이해가 부족해 구현하지 못하였다.

Lv2. 아날로그 시계

문제) PCCP 기출문제 3번 - 아날로그 시계
복사한 코드

접근방식

  1. 분침과 초침이 만날때만 count하면 되는 것이기때문에, 1초에 분침이 움직이는 각도와, 초침이 움직이는 각도를 구해야 함.
  2. 주어진 시작시각과 끝시각을 초단위로 변환해야 함.
  3. 주어진 시작시각과 끝시각 동안 분침과 초침이 이동한 각도를 계산해야함

구현코드

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)
풀이결과
중고등학교때 많이 나오는 문제라서 풀 수 있겠다 생각했다. (결론: 못품)
시간이 나오면 포맷팅을 어떻게 해야하는 지 머리가 하얘진다.
그래도 접근방식은 빨리 도달해서 다행이긴 했다.

Lv3. 수레 움직이기

문제) PCCP 기출문제 4번 - 수레 움직이기
참고링크 - C++

접근방식

구현코드

소요시간
풀지 못함. (문제 이해 - 10분, 접근 방식 - X, 구현 - X)
풀이결과
(추가예정)

profile
Just Do It

0개의 댓글