소토
소토의 기록하는 삶
소토
전체 방문자
오늘
어제
  • 분류 전체보기 (34)
    • Algorithm (34)
      • Problem (34)
    • Web (0)
    • ML & AI (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 알고리즘
  • 패캠챌린지
  • 백준
  • 패스트캠퍼스후기
  • 코드스테이츠
  • 문제
  • 직장인인강
  • 한번에끝내는JavaSpring웹개발마스터초격차패키지Online
  • 직장인자기계발
  • 패스트캠퍼스

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
소토

소토의 기록하는 삶

Algorithm/Problem

[Baekjoon] 21610번 : 마법사 상어와 비바라기 - Python

2022. 2. 11. 14:29

Gold 5

 

21610번: 마법사 상어와 비바라기

마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기

www.acmicpc.net

 

 

문제 풀이

구현 문제

문제에서 제시한 조건대로 차례차례 구현하면 되는 문제였다.

cloud 리스트를 따로 만들어 구름의 위치를 다룰 수 있게 했다.

 

코드

from copy import deepcopy

n, m = map(int, input().split())
map_ = []
for _ in range(n):
    map_.append(list(map(int, input().split())))
cloud = [[0] * n for _ in range(n)]


#  ←, ↖, ↑, ↗, →, ↘, ↓, ↙
mx = [0, -1, -1, -1, 0, 1, 1, 1]
my = [-1, -1, 0, 1, 1, 1, 0, -1]

def move_cloud(direction, x, y, dist):
    temp_x, temp_y = x, y

    for _ in range(dist):
        nx = mx[direction] + temp_x
        ny = my[direction] + temp_y

        # 범위 밖을 벗어날 경우 처리
        nx = n-1 if nx < 0 else nx
        ny = n-1 if ny < 0 else ny
        nx = 0 if nx >= n else nx
        ny = 0 if ny >= n else ny

        temp_x, temp_y = nx, ny

    return nx, ny

# 비바라기 시전
cloud[n-1][0], cloud[n-1][1], cloud[n-2][0], cloud[n-2][1] = 1, 1, 1, 1
count = 0

while True:
    if count == m:
        sum_ = 0
        for i in range(n):
            sum_ += sum(map_[i])
        print(sum_)
        break

    direction, distance = map(int, input().split())
    temp_cloud = [[0] * n for _ in range(n)]

    # 구름 이동
    for i in range(n):
        for j in range(n):
            if cloud[i][j] == 1:
                move_x, move_y = move_cloud(direction-1, i, j, distance)
                temp_cloud[move_x][move_y] = 1
                map_[move_x][move_y] += 1

    cloud = deepcopy(temp_cloud)

    # 물복사버그 마법 시전
    for i in range(n):
        for j in range(n):
            if cloud[i][j]:
                bucket = 0
                for k in range(4):
                    copy_direction = k*2 + 1
                    nx = i + mx[copy_direction]
                    ny = j + my[copy_direction]

                    if 0 <= nx < n and 0 <= ny < n and map_[nx][ny]:
                        bucket += 1
                # 물이 있는 바구니 수 만큼 물 증가
                map_[i][j] += bucket

    # 바구니에 저장된 물의 양이 2 이상인 모든 칸에 구름 생성
    # 물의 양 -2
    for i in range(n):
        for j in range(n):
            # 구름이 있는 칸은 구름 삭제
            if cloud[i][j]:
                cloud[i][j] = 0

            # 구름이 없으면서 2이상이면 구름이 생기고 물의 양 2 감소
            else :
                if map_[i][j] >= 2:
                    cloud[i][j] = 1
                    map_[i][j] -= 2

    count += 1

 

느낀점

1시간 40분 정도 소요

예전보단 빨라졌지만 어렵지 않은데 비해 잔 실수들 때문에 찾는데 시간이 좀 오래걸렸다 ㅎ.. 오타나 실수를 줄일 수 있도록 하자.

 

범위 밖을 벗어날 때를 이어가는 유형은 처음 봤는데 그 점이 지금까지 접해왔던 문제들과는 좀 달랐던 것 같다.

이런 경우에 이동하는 부분은 아래처럼 나머지를 계산 하는것이 더 깔끔하고 효율적이다.

nx = (x + mx[direction-1]*distance) % n
ny = (y + my[direction-1]*distance) % n
728x90
저작자표시 (새창열림)

'Algorithm > Problem' 카테고리의 다른 글

[Programmers] 타겟넘버 - Java  (0) 2022.02.17
[Baekjoon] 14499번 : 주사위 굴리기 - Python  (0) 2022.02.14
[Baekjoon] 14500 : 테트로미노 - Python  (0) 2022.02.10
[Baekjoon] 14891 : 톱니바퀴 - Python  (0) 2022.02.07
[Baekjoon] 15683번 : 감시 - Python  (0) 2022.02.04
    소토
    소토

    티스토리툴바