반응형
Notice
Recent Posts
Recent Comments
Link
It's easy, if you try
[백준/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<Ball>[][] 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<N; j++) {
map[i][j] = new ArrayList<Ball>();
}
}
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);
}
}
}
}
}
반응형
'알고리즘 > 자바(Java)' 카테고리의 다른 글
[백준/boj] 23290: 마법사 상어와 복제 (JAVA) / 구현 / DFS (1) | 2022.10.11 |
---|---|
[백준/boj] 20057: 마법사 상어와 토네이도(JAVA) / 구현 (0) | 2022.04.24 |
[백준/boj] 19238: 스타트 택시(JAVA) / 구현 / BFS (0) | 2021.10.16 |
[백준/boj] 5430: AC (Java) / Deque / 자료구조 (1) | 2021.09.25 |
[백준/boj] 17089: 세 친구 (Java) / 그래프 (0) | 2021.07.26 |
Comments