250128 마법사 상어와 토네이도

Jongleee·2025년 1월 28일
0

TIL

목록 보기
794/816
static class TornadoSimulation {
	private final int[][] grid;
	private final int size;
	private int sandOutside;

	private static final int[] dx = { -1, 1, 0, 0 };
	private static final int[] dy = { 0, 0, -1, 1 };
	private static final int[] nextDirection = { 2, 3, 1, 0 };
	private static final int[][] spreadX = {
			{ 1, 1, 0, 0, -2, 0, 0, -1, -1, -1 },
			{ -1, -1, 0, 0, 2, 0, 0, 1, 1, 1 },
			{ -1, 1, -2, 2, 0, -1, 1, -1, 1, 0 },
			{ -1, 1, -2, 2, 0, -1, 1, -1, 1, 0 }
	};
	private static final int[][] spreadY = {
			{ -1, 1, -2, 2, 0, -1, 1, -1, 1, 0 },
			{ -1, 1, -2, 2, 0, -1, 1, -1, 1, 0 },
			{ 1, 1, 0, 0, -2, 0, 0, -1, -1, -1 },
			{ -1, -1, 0, 0, 2, 0, 0, 1, 1, 1 }
	};
	private static final int[] spreadRate = { 1, 1, 2, 2, 5, 7, 7, 10, 10 };

	public TornadoSimulation(int[][] grid) {
		this.grid = grid;
		this.size = grid.length;
		this.sandOutside = 0;
	}

	public int run() {
		int centerX = size / 2;
		int centerY = size / 2;
		int currentDirection = 2;
		int step = 1;
		int turns = 0;

		while (centerX != 0 || centerY != 0) {
			for (int i = 0; i < step; i++) {
				int nextX = centerX + dx[currentDirection];
				int nextY = centerY + dy[currentDirection];

				moveSand(centerX, centerY, nextX, nextY, currentDirection);

				centerX = nextX;
				centerY = nextY;

				if (centerX == 0 && centerY == 0) {
					break;
				}
			}

			turns++;
			currentDirection = nextDirection[currentDirection];

			if (turns == 2) {
				step++;
				turns = 0;
			}
		}

		return sandOutside;
	}

	private void moveSand(int fromX, int fromY, int toX, int toY, int direction) {
		int sand = grid[toX][toY] += grid[fromX][fromY];
		grid[fromX][fromY] = 0;
		int remainingSand = sand;

		for (int i = 0; i < 9; i++) {
			int spreadXPos = toX + spreadX[direction][i];
			int spreadYPos = toY + spreadY[direction][i];
			int spreadAmount = sand * spreadRate[i] / 100;

			distributeSand(spreadXPos, spreadYPos, spreadAmount);
			remainingSand -= spreadAmount;
		}

		int alphaX = toX + spreadX[direction][9];
		int alphaY = toY + spreadY[direction][9];
		distributeSand(alphaX, alphaY, remainingSand);
		grid[toX][toY] = 0;
	}

	private void distributeSand(int x, int y, int amount) {
		if (x < 0 || x >= size || y < 0 || y >= size) {
			sandOutside += amount;
		} else {
			grid[x][y] += amount;
		}
	}
}

public static void main(String[] args) throws Exception {
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	int gridSize = Integer.parseInt(br.readLine());
	int[][] grid = new int[gridSize][gridSize];

	for (int i = 0; i < gridSize; i++) {
		StringTokenizer st = new StringTokenizer(br.readLine());
		for (int j = 0; j < gridSize; j++) {
			grid[i][j] = Integer.parseInt(st.nextToken());
		}
	}

	TornadoSimulation simulation = new TornadoSimulation(grid);
	System.out.println(simulation.run());
}

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

0개의 댓글

관련 채용 정보