코딩테스트/구현

마법사 상어와 토네이도

수타. 2023. 8. 2. 19:45

https://www.acmicpc.net/problem/20057

 

20057번: 마법사 상어와 토네이도

마법사 상어가 토네이도를 배웠고, 오늘은 토네이도를 크기가 N×N인 격자로 나누어진 모래밭에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c열을 의미하고, A[r][c]는 (r, c)에 있는 모래의 양을

www.acmicpc.net

문제요약:

특정 조건을 통해 2차원배열에서 토네이도가 생성되고 그에따라 원래있던 먼지들이 움직일때, 배열전체를 휩쓸고 남은 먼지의 합을 구하시오

 

난이도:

골드3

 

소요시간:

1시간

 

제출횟수:

1번

 

코딩:

import sys
input = sys.stdin.readline
import math
n = int(input())

arr= [list(map(int,input().split())) for _ in range(n)]
dy= [0,1,0,-1]
dx= [-1,0,1,0]
y = n//2
x = n//2
dir = 0    
#왼쪽으로 90도
def updir(dir):
    dir +=1
    if dir ==4:
        dir = 0
    return dir
#오른쪽으로 90도
def downdir(dir):
    dir -=1
    if dir == -1:
        dir = 3
    return dir
    
 
def diffusion(ny,nx,dir):
    dust = arr[ny][nx]
    arr[ny][nx] = 0
    y = ny -dy[dir]
    x = nx -dx[dir]
    #1퍼
    if 0<=y+dy[downdir(dir)] <n and 0<=x+dx[downdir(dir)]< n :
        arr[y+dy[downdir(dir)]][x+dx[downdir(dir)]] += math.floor(dust/100)
    if 0<=y+dy[updir(dir)] <n and 0<=x+dx[updir(dir)]< n :
        arr[y+dy[updir(dir)]][x+dx[updir(dir)]] += math.floor(dust/100)
    #7퍼
    if 0<=ny+dy[downdir(dir)] <n and 0<=nx+dx[downdir(dir)]< n :
        arr[ny+dy[downdir(dir)]][nx+dx[downdir(dir)]] += math.floor(7*dust/100)
    if 0<=ny+dy[updir(dir)] <n and 0<=nx+dx[updir(dir)]< n :
        arr[ny+dy[updir(dir)]][nx+dx[updir(dir)]] += math.floor(7*dust/100)
    #2퍼
    if 0<=ny+2*dy[downdir(dir)] <n and 0<=nx+2*dx[downdir(dir)]< n :
        arr[ny+2*dy[downdir(dir)]][nx+2*dx[downdir(dir)]] += math.floor(2*dust/100)
    if 0<=ny+2*dy[updir(dir)] <n and 0<=nx+2*dx[updir(dir)]< n :
        arr[ny+2*dy[updir(dir)]][nx+2*dx[updir(dir)]] += math.floor(2*dust/100)

    nny = ny +dy[dir]
    nnx = nx +dx[dir]
    #10퍼
    if 0<=nny+dy[downdir(dir)] <n and 0<=nnx+dx[downdir(dir)]< n :
        arr[nny+dy[downdir(dir)]][nnx+dx[downdir(dir)]] += math.floor(dust/10)
    if 0<=nny+dy[updir(dir)] <n and 0<=nnx+dx[updir(dir)]< n :
        arr[nny+dy[updir(dir)]][nnx+dx[updir(dir)]] += math.floor(dust/10)
    #5퍼
    if 0<=nny+dy[dir] <n and 0<=nnx+dx[dir]< n :
        arr[nny+dy[dir]][nnx+dx[dir]] += math.floor(dust/20)   
    if 0<=nny<n and 0<=nnx<n :
        arr[nny][nnx] += dust-2*math.floor(dust/100)-math.floor(dust/20)-2*math.floor(7*dust/100)-2*math.floor(dust/50)-2*math.floor(dust/10)
    
def move():
    global y
    global x
    global dir
    for _ in range(i):
        y+=dy[dir]
        x+=dx[dir]
        diffusion(y,x,dir)
    dir = updir(dir)   

ans = sum([j for i in arr for j in i])
#i는 이동할 거리
for i in range(1,n):
    move()
    move()
move()

print(ans - sum([j for i in arr for j in i]))

부르트포스 구현으로 풀었습니다.

 

다음 조건에 따라 토네이도가 이동하게 되는데, 이는 move()함수로 구현하였고, 처음에 시작할때부터 1씩 왼쪽 아래, 2씩 오른쪽 위쪽, 3씩 왼쪽 아래 4씩 오른쪽 위로 가는 규칙을 찾았고, 이를 통해 move()함수를 한번 들어가게되면 n-1까지 증가하는 i를 만들어 두번씩 통과하게하였습니다. 그리고 원래의 방향 기준으로 왼쪽으로 꺾으면 dir을 +=1하게 오른쪽으로 꺾으면 dir을 -=1하게 dir함수들을 만들었으며, 이를 통해 

dir에 따라 움직이는 게 바뀌는 토네이도도 dir로 상대적으로 구했습니다.