Gold 5,
이 문제는 런타임에러가 굉장히 발목을 잡았는데, 모듈러연산을 이용하여 마법사 상어의 이동을 처리했다고 생각했는데 오산이었다.
스피드가 엄청나게 클 경우 모듈러 연산을 사용하여도 런타임 에러가 발생할 수 있다.
파이어볼 문제에서는 맵을 중심으로 풀건지 파이어볼을 중심으로 풀 건지를 선택해야한다.
나의 경우엔 파이어볼 객체에 파이어볼의 위치도 넣어주면서 리스트로 관리하는 방식으로 코딩하였다.
예외 처리에 특히 주의한다면 큰 무리는 없는 문제라고 생각한다.
import java.io.*;
import java.util.*;
class Main {
static int N, M, K, answer;
static List<FireBall>[][] map;
static int[][] dirs = {{-1, 0},{-1, 1},{0, 1},{1,1},{1, 0},{1, -1},{0, -1},{-1, -1}};
static List<FireBall> listFireBall;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
map = new LinkedList[N+1][N+1];
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= N; j++) {
map[i][j] = new LinkedList<>();
}
}
listFireBall = new LinkedList<>();
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int r = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int s = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
FireBall cur= new FireBall(r, c, m, s, d);
listFireBall.add(cur);
}
while(K-- > 0) {
move();
chageFileBall();
}
System.out.println(count());
}
public static int count() {
int result = 0;
for(FireBall fb : listFireBall) {
result += fb.m;
}
return result;
}
//볼을 나누는 메서드
public static void chageFileBall() {
listFireBall = new LinkedList<>();
for (int i = 1; i<= N ; i++) {
for (int j = 1; j <= N; j++) {
if(map[i][j].size() == 0) continue;
if(map[i][j].size() == 1) {
listFireBall.add(map[i][j].get(0));
continue;
}
int sumM = 0;
int sumSpeed = 0;
//방향이 홀수라면 감소 시킬 것. 초기값이나 0이 아니라면 방향의 홀짝이 다른 값.
int dirCnt = map[i][j].size();
for(FireBall fb : map[i][j]) {
sumM += fb.m;
sumSpeed += fb.s;
if(fb.d % 2 == 1) dirCnt--;
}
sumM /=5;//총 질량
sumSpeed /= map[i][j].size();
if(sumM == 0) continue;
int start = 1;
int end = 7;
if(dirCnt == 0 || dirCnt == map[i][j].size()) {
start = 0;
end = 6;
}
//공들을 위치에 넣어주는 부분으로 안 하는게 맞지만 해도 정답에는 이상없음.
for (int dir = start; dir <= end; dir+=2) {
// int nextR = i + dirs[dir][0];
// int nextC = j + dirs[dir][1];
// nextR %= N;
// nextC %= N;
// System.out.println(i+":"+j);
listFireBall.add(new FireBall(i, j, sumM, sumSpeed, dir));
}
}
}
}
public static void move() {
map = new LinkedList[N+1][N+1];
for(int i = 1; i <=N; i++) {
for(int j = 1; j <=N; j++) {
map[i][j] = new LinkedList<>();
}
}
for(FireBall fireBall : listFireBall) {
int r = fireBall.row;
int c = fireBall.col;
int m = fireBall.m;
int s = fireBall.s;
int d = fireBall.d;
//배열 범위내로 들어오게 하기 위함.
r += (dirs[d][0] *s) + N;
c += (dirs[d][1] *s) + N;
r %= N;
c %= N;
r = r == 0? N : r;
c = c == 0? N : c;
r = r < 0? r + N: r;
c = c < 0? c + N: c;
map[r][c].add(new FireBall(r, c, m, s, d));
}
}
}
class FireBall{
int row;
int col;
int m;
int s;
int d;
FireBall(int r, int c, int m, int s, int d){
this.row = r;
this.col = c;
this.m = m;
this.s = s;
this.d = d;
}
}
반응형
'알고리즘 문제 풀이 > BOJ' 카테고리의 다른 글
[backjoon]15684 사다리 조작 java (0) | 2021.09.01 |
---|---|
[backjoon]14720 우유 도시 java (0) | 2021.05.08 |
[backjoon]14500 테트로미노 java (0) | 2021.04.23 |
[backjoon]16235 나무재테크 java (0) | 2021.04.22 |
[backjoon]20058 마법사 상어와 파이어 스톰 java (0) | 2021.04.20 |