본문 바로가기

알고리즘/SW 역량 테스트

[백준] 20056. 마법사 상어와 파이어볼

반응형

https://www.acmicpc.net/problem/20056

 

20056번: 마법사 상어와 파이어볼

첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치

www.acmicpc.net


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;
	}
}
반응형