[백준/boj] 20056: 마법사 상어와 파이어볼(JAVA) / 구현

[백준/boj] 20056: 마법사 상어와 파이어볼(JAVA) / 구현

풀이

import java.io.*; import java.util.*; public class Main { static int[] dx = { -1, -1, 0, 1, 1, 1, 0, -1}; static int[] dy = { 0, 1, 1, 1, 0, -1, -1, -1}; static List[][] map; static int N; static class Ball { int x, y, m, s, d; // cnt는 맵에 내가 몇번째인지. boolean isMoved; Ball(int x, int y, int m, int s, int d, boolean isMoved) { this.x = x; this.y = y; this.m = m; this.s = s; this.d = d; this.isMoved = isMoved; } } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); // 행, 열 크기 int M = Integer.parseInt(st.nextToken()); // 파이어볼 개수 int K = Integer.parseInt(st.nextToken()); // 명령 횟수 map = new ArrayList[N][N]; for(int i=0; i< N; i++) { for(int j=0; j(); } } for (int i = 1; i <= M; i++) { // 볼의 번호는 1~M st = new StringTokenizer(br.readLine()); int x = Integer.parseInt(st.nextToken())-1; // 좌표가 1~N으로 주어지면 -1 하기! int y = Integer.parseInt(st.nextToken())-1; int m = Integer.parseInt(st.nextToken()); int s = Integer.parseInt(st.nextToken()); int d = Integer.parseInt(st.nextToken()); Ball ball = new Ball(x, y, m, s, d, false); map[x][y].add(ball); } int cnt = 0; int answer = 0; while (cnt < K) { // 이동 // 시간줄이려면 if(move()true일때만 sumAndDivide) move(); // 합치기 sumAndDivide(); // 0인 파이어볼 소멸 answer = kill(); cnt++; } System.out.println(answer); } private static int kill() { int sum = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if(map[i][j].size() == 0) continue; int cnt = map[i][j].size(); for(int c=cnt-1; c>=0; c--) { if(map[i][j].get(c).m == 0) map[i][j].remove(c); else { map[i][j].get(c).isMoved = false; sum += map[i][j].get(c).m; } } } } return sum; } private static void sumAndDivide() { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (map[i][j].size() < 2) continue; // 2개 이상이면 int size = map[i][j].size(); int cnt = 0; // 파이어볼 개수 int sumM = 0; // 질량 합 int sumS = 0; // 속력 합 boolean isEven = true; // 모든 방향이 짝수? boolean isOdd = true; // 모든 방향이 홀수? for (int c = size - 1; c >= 0; c--) { cnt++; sumM += map[i][j].get(c).m; sumS += map[i][j].get(c).s; if (map[i][j].get(c).d % 2 == 0) { // 방향이 짝수 isOdd = false; } else { // 홀수 isEven = false; } } map[i][j].clear(); int newM = sumM / 5; int newS = sumS / cnt; // 모두 짝수인지 홀수인지 if (isOdd || isEven) { map[i][j].add(new Ball(i, j, newM, newS, 0, false)); map[i][j].add(new Ball(i, j, newM, newS, 2, false)); map[i][j].add(new Ball(i, j, newM, newS, 4, false)); map[i][j].add(new Ball(i, j, newM, newS, 6, false)); } else { map[i][j].add(new Ball(i, j, newM, newS, 1, false)); map[i][j].add(new Ball(i, j, newM, newS, 3, false)); map[i][j].add(new Ball(i, j, newM, newS, 5, false)); map[i][j].add(new Ball(i, j, newM, newS, 7, false)); } } } } private static void move() { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if(map[i][j].size() == 0) continue; int cnt = map[i][j].size(); for(int c = cnt-1; c>=0; c--) { if(map[i][j].get(c).isMoved) continue; // 이미 움직였던 볼이면 안움직임 Ball ball = map[i][j].get(c); map[i][j].remove(c); int x = ball.x; int y = ball.y; int nx = x, ny = y; for (int s = 0; s < ball.s; s++) { // 속력만큼 이동 nx = x + dx[ball.d]; ny = y + dy[ball.d]; // 모든 벽은 이어져있음. if(nx < 0) { nx = N -1; } else if(nx >= N) { nx = 0; } if(ny >= N) { ny = 0; } else if(ny < 0) { ny = N -1; } x = nx; y = ny; } ball.x = x; ball.y = y; ball.isMoved = true; map[ball.x][ball.y].add(ball); } } } } }

from http://sohee-dev.tistory.com/139 by ccl(A) rewrite - 2021-10-17 15:01:57