반응형
https://www.acmicpc.net/problem/20056
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Main {
static class FireBall {
int r, c, m, s, d;
FireBall(int r, int c, int m, int s, int d){
this.r=r;
this.c=c;
this.m=m;
this.s=s;
this.d=d;
}
}
static int N, M, K;
static int[][] map;
static int[][] dir = {{-1,0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
static ArrayList<FireBall> balls;
static ArrayList<FireBall> temp_balls;
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
temp_balls = new ArrayList();
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());
temp_balls.add(new FireBall(R, C, M, S, D));
}
for(int i=0; i<K; i++) {
map = new int[N+1][N+1];
balls = new ArrayList(temp_balls);
temp_balls.clear();
// 1. 모든 파이어볼이 자신의 방향 d로 속력 s칸 만큼 이동한다.
for(int j=0; j<balls.size(); j++) {
FireBall fb = balls.get(j);
int nx = fb.r;
int ny = fb.c;
// 속력 s만큼 칸 이동
for(int k=0; k<fb.s; k++) {
nx += dir[fb.d][0];
ny += dir[fb.d][1];
// 범위 밖을 벗어나면
if(!isInside(nx, ny)) {
if(nx == 0) nx = N;
else if(nx == N+1) nx = 1;
if(ny == 0) ny = N;
else if(ny == N+1) ny = 1;
}
}
// 파이어볼 위치 갱신
balls.set(j, new FireBall(nx, ny, fb.m, fb.s, fb.d));
// map에 파이어볼 갯수 표시.
map[nx][ny] += 1;
}
// 이동이 모두 끝난 뒤, map에 2개 이상의 파이어볼이 있는 칸 확인.
for(int j=1; j<=N; j++) {
for(int k=1; k<=N; k++) {
// 2개 이상의 파이어볼이 있는 칸 확인.
if(map[j][k] >= 2) {
int sumM=0; // 질량의합
int sumS=0; // 속력의합
int cnt=0; // 파이어볼 갯수
int add=0; // 홀수
int even=0; // 짝수
for(int l=0; l<balls.size(); l++) {
FireBall fb = balls.get(l);
if(fb.r == j && fb.c == k) {
sumM += fb.m;
sumS += fb.s;
cnt++;
// 파이어볼의 방향이 짝수이면
if(fb.d % 2 == 0) even++;
else add++;
balls.remove(l);
l--;
}
}
// 질량은 질량의합/5
int tempM = sumM/5;
// 질량이 0인 파이어볼은 소멸되어 없어진다.
if(tempM <= 0) continue;
// 속력은 속력의합/파이어볼갯수
int tempS = sumS / cnt;
// 2개이상의 파이어볼이 있는 좌표에 파이어볼이 4개로 나누어진다.
// 합쳐지는 파이어볼의 방향이 모두 홀수이거나 짝수이면 방향은 0,2,4,6 아니면 1,3,5,7
if(cnt == even || cnt == add) {
temp_balls.add(new FireBall(j, k, tempM, tempS, 0));
temp_balls.add(new FireBall(j, k, tempM, tempS, 2));
temp_balls.add(new FireBall(j, k, tempM, tempS, 4));
temp_balls.add(new FireBall(j, k, tempM, tempS, 6));
} else {
temp_balls.add(new FireBall(j, k, tempM, tempS, 1));
temp_balls.add(new FireBall(j, k, tempM, tempS, 3));
temp_balls.add(new FireBall(j, k, tempM, tempS, 5));
temp_balls.add(new FireBall(j, k, tempM, tempS, 7));
}
}
}
}
// balls 에 남아있는거 temp_balls에 추가
for(FireBall fb : balls) {
temp_balls.add(fb);
}
}
int answer = 0;
for(FireBall fb : temp_balls) {
answer += fb.m;
}
System.out.println(answer);
}
public static boolean isInside(int x, int y) {
return x>=1&&y>=1&&x<=N&&y<=N;
}
}
반응형
'알고리즘 > SW 역량 테스트' 카테고리의 다른 글
[백준] 23291. 어항 정리 (0) | 2022.04.22 |
---|---|
[백준] 21608. 상어 초등학교 (0) | 2021.10.01 |
[백준] 20057. 마법사 상어와 토네이도 (0) | 2021.08.23 |
[백준] 20058. 마법사 상어와 파이어스톰 (0) | 2021.08.11 |
[백준] 21610. 마법사 상어와 비바라기 (0) | 2021.08.08 |