본문으로 바로가기

 

삼성 기출문제 상어시리즈의 마지막 문제인 마법사 상어와 파이어볼이다. 개인적인 난이도의 체감은 청소년 상어가 가장 높았고, 이 문제가 아기상어 다음으로 쉬웠다고 생각한다.

유일하게 조금 고민되는 부분이,

 격자의 행과 열은 1번부터 N번까지 번호가 매겨져 있고, 1번 행은 N번 행과 연결되어 있고, 1번 열은 N번 열과 연결되어 있다.
이 조건이 조금 어렵게 읽히지만, 아래의 예시와 함께 천천히 읽어보면 쉽게 이해할 수 있다. ( 사소한 오타도 있어서 좀 더 어렵게 느꼈던 것 같다.)

 

구현 순서

 

1. 파이어볼 이동

 

	private static void move() {
		for (Fire f : fires) {
			int nx = (f.x + N + dir[f.d][0] * (f.s % N)) % N;
			int ny = (f.y + N + dir[f.d][1] * (f.s % N)) % N;
			f.x = nx;
			f.y = ny;
			map[nx][ny].add(f);
		}
	}


2. 이차원리스트로 생성한 Fire 객체의 특정 좌표에 2개 이상의 파이어볼이 있다면, 규칙에 따라 합친 후 4개로 재분할한다.

	private static void split() {
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (map[i][j].size() <= 1) {
					map[i][j].clear();
					continue;
				}
				int mSum = 0;
				int sSum = 0;
				boolean even = map[i][j].get(0).d % 2 == 0 ? true : false;
				boolean odd = map[i][j].get(0).d % 2 == 1 ? true : false;
				for (Fire f : map[i][j]) {
					mSum += f.m;
					sSum += f.s;
					even = even & f.d % 2 == 0 ? true : false;
					odd = odd & f.d % 2 == 1 ? true : false;
					fires.remove(f);
				}
				int nMass = mSum / 5;
				int size = map[i][j].size();
				map[i][j].clear();
				int nSpeed = sSum / size;

				if (nMass == 0) {
					continue;
				}

				if (even | odd) { // 0 2 4 6
					for (int k = 0; k < 8; k += 2) {
						fires.add(new Fire(i, j, nMass, nSpeed, k));
					}
				} else {
					for (int k = 1; k < 8; k += 2) {
						fires.add(new Fire(i, j, nMass, nSpeed, k));
					}
				}
			}
		}

	}


3. K초가 지난 후 파이어볼 질량의 합

		int res = 0;
		for (Fire f : fires) {
			res += f.m;
		}
		System.out.println(res);

코드 전문

package samsung;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;


public class BOJ_20056_마법사상어와파이어볼 {
	static int N, M, K;
	static int[][] dir = { { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 } };
	static List<Fire>[][] map;
	static List<Fire> fires = new ArrayList<>();

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		N = stoi(st.nextToken());
		M = stoi(st.nextToken());
		K = stoi(st.nextToken());
		map = new List[N][N];
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				map[i][j] = new ArrayList<>();
			}
		}
		for (int i = 0; i < M; i++) {
			st = new StringTokenizer(br.readLine());
			int x = stoi(st.nextToken()) - 1;
			int y = stoi(st.nextToken()) - 1;
			int m = stoi(st.nextToken());
			int s = stoi(st.nextToken());
			int d = stoi(st.nextToken());
			fires.add(new Fire(x, y, m, s, d));

		}
		for (int i = 0; i < K; i++) {
			move();
			split();
		}
		int res = 0;
		for (Fire f : fires) {
			res += f.m;
		}
		System.out.println(res);

	}

	private static void split() {
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (map[i][j].size() <= 1) {
					map[i][j].clear();
					continue;
				}
				int mSum = 0;
				int sSum = 0;
				boolean even = map[i][j].get(0).d % 2 == 0 ? true : false;
				boolean odd = map[i][j].get(0).d % 2 == 1 ? true : false;
				for (Fire f : map[i][j]) {
					mSum += f.m;
					sSum += f.s;
					even = even & f.d % 2 == 0 ? true : false;
					odd = odd & f.d % 2 == 1 ? true : false;
					fires.remove(f);
				}
				int nMass = mSum / 5;
				int size = map[i][j].size();
				map[i][j].clear();
				int nSpeed = sSum / size;

				if (nMass == 0) {
					continue;
				}

				if (even | odd) { // 0 2 4 6
					for (int k = 0; k < 8; k += 2) {
						fires.add(new Fire(i, j, nMass, nSpeed, k));
					}
				} else {
					for (int k = 1; k < 8; k += 2) {
						fires.add(new Fire(i, j, nMass, nSpeed, k));
					}
				}
			}
		}

	}

	private static void move() {
		for (Fire f : fires) {
			int nx = (f.x + N + dir[f.d][0] * (f.s % N)) % N;
			int ny = (f.y + N + dir[f.d][1] * (f.s % N)) % N;
			f.x = nx;
			f.y = ny;
			map[nx][ny].add(f);
		}
	}

	static class Fire {
		int x;
		int y;
		int m;
		int s;
		int d;

		public Fire(int x, int y, int m, int s, int d) {
			this.x = x;
			this.y = y;
			this.m = m;
			this.s = s;
			this.d = d;
		}

	}

	private static boolean isValid(int x, int y) {
		return 0 <= x && 0 <= y && x < N && y < N;
	}

	public static int stoi(String s) {
		return Integer.parseInt(s);
	}

}