티스토리 뷰

//알고리즘

1. 시뮬레이션

2. 주어진 조건에 맞춰 구현하면 됨.

3. 기본기 탄탄하게 해주는 좋은 문제라고 생각됨.  

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class 마법사상어와토네이도_20057 {
	static int N, map[][], ans;
	static int[] dr = { -2, -1, -1, -1 }; // ㅗ 모양
	static int[] dc = { 0, -1, 0, 1 };
	static double[] uRatio = { 0.02, 0.1, 0.07, 0.01 };
	static double[] dRatio = { 0.02, 0.01, 0.07, 0.1 };

	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];

		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());
			}
		}

		cal(map);

//		print(map);
		System.out.println(ans);

	}

	private static void cal(int[][] map) {
		int r = N / 2;
		int c = N / 2;
		int sw = 0;
		int num = 1;
		int cnt = 1;
		while (true) {

			if (sw == 0) {
				for (int i = 0; i < cnt; i++) {
					leftCal(r, --c);
//					map[r][--c] = num++;
				}
				for (int i = 0; i < cnt; i++) {
					downCal(++r, c);
//					map[++r][c] = num++;
				}
				sw = 1;
			} else {
				for (int i = 0; i < cnt; i++) {
					rightCal(r, ++c);
//					map[r][++c] = num++;
				}
				for (int i = 0; i < cnt; i++) {
					upCal(--r, c);
//					map[--r][c] = num++;
				}
				sw = 0;
			}
			cnt++;
			if (cnt == N) {
				for (int i = 1; i < cnt; i++) {
					leftCal(r, --c);
//					map[r][--c] = num++;
				}
				break;
			}
		}
	}

	private static void upCal(int r, int c) {
		int sum = 0;
		for (int k = 0; k < 4; k++) {
			int nr = r + dc[k];
			int nc = c + dr[k];

			if (!check(nr, nc)) {
				ans += (int) map[r][c] * uRatio[k];
				sum += (int) map[r][c] * uRatio[k];
				continue;
			}

			map[nr][nc] += (int) map[r][c] * uRatio[k];
			sum += (int) map[r][c] * uRatio[k];
		}

		for (int k = 0; k < 4; k++) {
			int nr = r + dc[k] * -1;
			int nc = c + dr[k] * -1;

			if (!check(nr, nc)) {
				ans += (int) map[r][c] * dRatio[k];
				sum += (int) map[r][c] * dRatio[k];
				continue;
			}

			map[nr][nc] += (int) map[r][c] * dRatio[k];
			sum += (int) map[r][c] * dRatio[k];
		}

		int nc = c;

		int nr = r - 2;
		if (!check(nr, nc)) {
			ans += (int) map[r][c] * 0.05;
			sum += (int) map[r][c] * 0.05;
		} else {
			map[nr][nc] += (int) map[r][c] * 0.05;
			sum += (int) map[r][c] * 0.05;
		}

		nr = r - 1;
		if (!check(nr, nc)) {
			ans += map[r][c] - sum;
		} else {
			map[nr][nc] += map[r][c] - sum;
		}

		map[r][c] = map[++r][c];

	}

	private static void downCal(int r, int c) {
		int sum = 0;
		for (int k = 0; k < 4; k++) {
			int nr = r + dc[k];
			int nc = c + dr[k];

			if (!check(nr, nc)) {
				ans += (int) map[r][c] * dRatio[k];
				sum += (int) map[r][c] * dRatio[k];
				continue;
			}

			map[nr][nc] += (int) map[r][c] * dRatio[k];
			sum += (int) map[r][c] * dRatio[k];
		}

		for (int k = 0; k < 4; k++) {
			int nr = r + dc[k] * -1;
			int nc = c + dr[k] * -1;

			if (!check(nr, nc)) {
				ans += (int) map[r][c] * uRatio[k];
				sum += (int) map[r][c] * uRatio[k];
				continue;
			}

			map[nr][nc] += (int) map[r][c] * uRatio[k];
			sum += (int) map[r][c] * uRatio[k];
		}

		int nc = c;

		int nr = r + 2;
		if (!check(nr, nc)) {
			ans += (int) map[r][c] * 0.05;
			sum += (int) map[r][c] * 0.05;
		} else {
			map[nr][nc] += (int) map[r][c] * 0.05;
			sum += (int) map[r][c] * 0.05;
		}

		nr = r + 1;
		if (!check(nr, nc)) {
			ans += map[r][c] - sum;
		} else {
			map[nr][nc] += map[r][c] - sum;
		}

		map[r][c] = map[--r][c];

	}

	private static void rightCal(int r, int c) {
		int sum = 0;
		for (int k = 0; k < 4; k++) {
			int nr = r + dr[k];
			int nc = c + dc[k];

			if (!check(nr, nc)) {
				ans += (int) map[r][c] * dRatio[k];
				sum += (int) map[r][c] * dRatio[k];
				continue;
			}

			map[nr][nc] += (int) map[r][c] * dRatio[k];
			sum += (int) map[r][c] * dRatio[k];
		}

		for (int k = 0; k < 4; k++) {
			int nr = r + dr[k] * -1;
			int nc = c + dc[k] * -1;

			if (!check(nr, nc)) {
				ans += (int) map[r][c] * uRatio[k];
				sum += (int) map[r][c] * uRatio[k];
				continue;
			}

			map[nr][nc] += (int) map[r][c] * uRatio[k];
			sum += (int) map[r][c] * uRatio[k];
		}

		int nr = r;

		int nc = c + 2;
		if (!check(nr, nc)) {
			ans += (int) map[r][c] * 0.05;
			sum += (int) map[r][c] * 0.05;
		} else {
			map[nr][nc] += (int) map[r][c] * 0.05;
			sum += (int) map[r][c] * 0.05;
		}

		nc = c + 1;
		if (!check(nr, nc)) {
			ans += map[r][c] - sum;
		} else {
			map[nr][nc] += map[r][c] - sum;
		}

		map[r][c] = map[r][--c];

	}

	private static void leftCal(int r, int c) {
		int sum = 0;
		for (int k = 0; k < 4; k++) {
			int nr = r + dr[k];
			int nc = c + dc[k];

			if (!check(nr, nc)) {
				ans += (int) map[r][c] * uRatio[k];
				sum += (int) map[r][c] * uRatio[k];
				continue;
			}

			map[nr][nc] += (int) map[r][c] * uRatio[k];
			sum += (int) map[r][c] * uRatio[k];
		}

		for (int k = 0; k < 4; k++) {
			int nr = r + dr[k] * -1;
			int nc = c + dc[k] * -1;

			if (!check(nr, nc)) {
				ans += (int) map[r][c] * dRatio[k];
				sum += (int) map[r][c] * dRatio[k];
				continue;
			}

			map[nr][nc] += (int) map[r][c] * dRatio[k];
			sum += (int) map[r][c] * dRatio[k];
		}

		int nr = r;

		int nc = c - 2;
		if (!check(nr, nc)) {
			ans += (int) map[r][c] * 0.05;
			sum += (int) map[r][c] * 0.05;
		} else {
			map[nr][nc] += (int) map[r][c] * 0.05;
			sum += (int) map[r][c] * 0.05;
		}

		nc = c - 1;
		if (!check(nr, nc)) {
			ans += map[r][c] - sum;
		} else {
			map[nr][nc] += map[r][c] - sum;
		}

		map[r][c] = map[r][++c];

	}

	// 경계선 넘어간 모래
	private static boolean check(int nr, int nc) {
		if (nr < 0 || nc < 0 || nr >= N || nc >= N)
			return false;
		return true;
	}

	private static void print(int[][] map) {
		// TODO Auto-generated method stub
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				System.out.print(map[i][j] + " ");
			}
			System.out.println();
		}
	}

}

'Algorithm' 카테고리의 다른 글

백준_여왕벌_10836  (0) 2020.10.28
백준_치즈_2636  (0) 2020.10.27
SW Expert Academy_보급로  (0) 2020.10.25
백준_마법사상어와파이어볼_20056  (0) 2020.10.24
백준_게리맨더링_17471  (0) 2020.10.23
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함