robert-min / dev-blog

김민준 - project 정리한 repo입니다.
0 stars 0 forks source link

240322 - PCCP #134

Open robert-min opened 6 months ago

robert-min commented 6 months ago

문제

  1. 붕대감기 링크
  2. 석유시추 링크
  3. 아날로그 시계 링크
  4. 수레 움직이기 링크
robert-min commented 6 months ago

붕대감기

def solution(bandage, health, attacks):
    """
    Return : 모든 공격이 끝나고 남은 체력 / 체력이 0이하가 되면 -1
    - bandage = [t, x, y] -> t초 연속으로 최력회복하면 y 추가 회복
    - health
    - attacks = [[공격 시간, 피해량]]

    time -> attacks[-1][0] 까지
    연속 회복 시간 = conti : 공격받으면 0으로 초기화 / == t이면 health += y
    공격 받는 수간 - attacks[i][1] 피해, 체력 회복 X
    """
    time = 0
    conti = 0
    now = health
    heal = bandage[1]
    # time <= attacks[-1][0]
    while attacks:
        time += 1
        # 공격
        if time == attacks[0][0]:
            now -= attacks[0][1]
            # health -= heal
            conti = 0
            attacks.pop(0)
        else:
            # 기본 회복
            now += heal

            conti += 1
            # 추가 회복
            if conti == bandage[0]:
                now += bandage[2]
                conti = 0
            if now > health:
                now = health

        if now <= 0:
            break

    answer = -1
    if now > 0:
        answer = now        

    return answer
robert-min commented 6 months ago

석유시추

from collections import deque

dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
def bfs(land, visited, answer_list, row, col):
    global N, M
    Q = deque([(row, col)])
    cnt = 1
    visited[row][col] = 1
    # 탐색할 때 면적과 만나는 열번호를 저장
    visited_col = [col]

    while Q:
        x, y = Q.popleft()
        for k in range(4):
            nx = x + dx[k]
            ny = y + dy[k]
            if nx < 0 or ny < 0 or nx >= N or ny >= M: continue
            if land[nx][ny] == 1 and not visited[nx][ny]:
                visited[nx][ny] = 1
                if ny not in visited_col:
                    visited_col.append(ny)

                Q.append((nx, ny))
                cnt += 1
    # 저장된 열번호에 탐색된 면적 추가
    for connected_col in visited_col:
        answer_list[connected_col] += cnt

def solution(land):
    """
    Return : 가장 많이 석유를 뽑을 때 석유 량
    land : 0 = 땅, 1 = 석유

    - col 기준으로 확인
    - 이미 확인된 칸은 확인할 필요가 없음
    - 탐색시도 할 때마다 탐색된 곳은 visited, cnt += 1
    - max_cnt 확인
    """
    global N, M
    N = len(land)
    M = len(land[0])

    answer_list = [0 for _ in range(M)]
    visited = [[0] * M for _ in range(N)]
    for i in range(N):
        for j in range(M):
            if land[i][j] == 1 and not visited[i][j]:
                bfs(land, visited, answer_list, i, j)
    answer = max(answer_list)
    return answer

dx = [-1, 1, 0, 0] dy = [0, 0, -1, 1] def bfs(land, visited, row, col, cnt): global N, M Q = deque([(row, col)]) visited[row][col] = 1 cnt += 1

while Q:
    x, y = Q.popleft()
    for k in range(4):
        nx = x + dx[k]
        ny = y + dy[k]
        if nx < 0 or ny < 0 or nx >= N or ny >= M: continue

        if land[nx][ny] == 1 and not visited[nx][ny]:
            cnt += 1
            visited[nx][ny] = 1
            Q.append((nx, ny))
return visited, cnt

def solution(land): """ Return : 가장 많이 석유를 뽑을 때 석유 량 land : 0 = 땅, 1 = 석유

- col 기준으로 확인
- 이미 확인된 칸은 확인할 필요가 없음
- 탐색시도 할 때마다 탐색된 곳은 visited, cnt += 1
- max_cnt 확인
"""
global N, M
N = len(land)
M = len(land[0])

# 동일 열, 행마다 칸 확인
max_cnt = 0
# TODO : 탐색은 한번만 해서 해당 값을 visited에 넣어 놓는 것으로 코드 수정
for col in range(M):
    visited = [[0] * M for _ in range(N)]
    cnt = 0
    for row in range(N):
        if not visited[row][col] and land[row][col] == 1:
            # 탐색
            visited, cnt = bfs(land, visited, row, col, cnt)

    max_cnt = max(max_cnt, cnt)
answer = max_cnt
return answer
robert-min commented 6 months ago

아날로그 시계

def solution(h1, m1, s1, h2, m2, s2):
    """
    Return : 알람이 울리는 횟수
    - 초침이 시침 or 분침과 겹칠 때
    - h1, m1, s1, ~ h2, m2, s2

    시침 1시간 = 30도 -> 1초 30 / 3600 -> 1초에 1/120도 이동
    분침 1분 = 6도 -> 1초 6 / 60 -> 1초에 1/10도 이동
    초침 1분 = 6도 -> 1초 6도 이동
    """
    answer = 0
    # 초단위 변경
    start_time = h1 * 3600 + m1 * 60 + s1
    end_time = h2 * 3600 + m2 * 60 + s2

    # 시작시간과 끝시간을 초단위로 변환
    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

        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