어제의 나보다 성장한 오늘의 나

[백준][BOJ-20057][Java] 마법사 상어와 토네이도 본문

알고리즘/백준(BOJ)

[백준][BOJ-20057][Java] 마법사 상어와 토네이도

NineOne 2021. 5. 19. 23:58

www.acmicpc.net/problem/20057

 

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

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

www.acmicpc.net

문제풀이

먼저 문제를 이해하는데 시간이 조금 걸렸다.

토네이도는 한 칸 이동할 때마다 모래는 다음과 같이 일정한 비율로 흩날리게 된다. 각 흩날리는 자리를 방향마다

저장하는 배열을 따로 만들어 주고 비율 또한 따로 배열로 저장하여 조건이 맞게 처리해주면 되는 문제였다.

2차원 배열로 깔끔하게 구현하는데 어려움이 있었다.

 

방향의 전환 같은 경우는 밑에서 오른쪽으로 갈 때와 위에서 왼쪽으로 갈 때마다 한 칸씩 더 전진하는 규칙성이 있어 방향 전환 변수를 따로 두었다. 그리고 흩뿌리기 같은 경우 9개의 비율 중 범위를 벗어나면 결괏값에 더해주고 알 파또 한 범위를 벗어나면 더하게 한번 더 검사를 하였다.

코드

import java.io.*;
import java.util.*;

public class Main {
	static int sum, N, toneX, toneY, dis;
	static int[][] map;
	static int[] dx = {0,1,0,-1};
	static int[] dy = {-1,0,1,0};
	static int[][] ratioX = {{0,-1,-1,-2,-1,1,1,2,1},
							{2,1,0,0,-1,1,0,0,-1},
							{0,1,1,2,1,-1,-1,-2,-1},
							{-2,-1,0,0,1,-1,0,0,1}};
	static int[][] ratioY = {{-2,-1,0,0,1,-1,0,0,1},
							{0,-1,-1,-2,-1,1,1,2,1},
							{2,1,0,0,-1,1,0,0,-1},
							{0,1,1,2,1,-1,-1,-2,-1}};
	static double[] ratioNum = {0.05,0.1,0.07,0.02,0.01,0.1,0.07,0.02,0.01};
	
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		N = Integer.parseInt(br.readLine());
		map= new int[N][N];
		toneX = N/2;
		toneY = N/2;
		
		for(int i=0; i<N; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			for(int j=0; j<N; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		int index =1;
		int tempIndex = 1;
		//토네이도 이동
		while(true) {
			if(toneX == 0 && toneY == 0) break;
			int d = dis%4;
			toneX += dx[d];
			toneY += dy[d];
			tempIndex--;
				
			//알파값
			int alpa = map[toneX][toneY];
			int fix = map[toneX][toneY];
			
			//이동한 모래 초기화
			map[toneX][toneY] = 0;
			
			//흙 뿌리기
			for(int k=0; k<9; k++) {
				int x = toneX + ratioX[d][k];
				int y = toneY + ratioY[d][k];
				int num = (int) (fix * ratioNum[k]);
				
				if(x <0 || x>=N || y<0 || y>=N) {
					sum += num;
					alpa -= num;
					continue;
				}
				
				map[x][y] += num;
				alpa -= num;
			}
			
			//알파 범위 검사
			if(toneX+dx[d] <0 || toneX+dx[d]>=N || toneY+dy[d]<0 || toneY+dy[d]>=N) sum += alpa;
			else map[toneX+dx[d]][toneY+dy[d]] += alpa;
				
			//방향전환
			if(tempIndex == 0) {
				dis++;
				if(dis%4 == 2) index++;
				else if(dis%4 == 0) index++;
				
				tempIndex = index;
			}
		}
		
		System.out.println(sum);
	}
}
Comments