알고리즘

백준 20056번 마법사 상어와 파이어볼 (JAVA)

박카스마시며코딩 2022. 3. 28. 13:20

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

 

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

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

www.acmicpc.net

 

 저는 Queue를 이용해 각각의 파이어볼의 정보를 입력받았습니다.

이를 List<Node>[][] map에 넣고 각각의 사이즈를 보면서 파이어볼이 겹치는 곳이 있는지 확인하였습니다.

파이어볼이 겹친다면 문제의 규칙에 따라 4개로 나눠주었습니다.

 

package BOJ.Simulation;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.function.Function;

public class BOJ_20056 {
    private static class Node{
        int y;
        int x;
        int weight;
        int speed;
        int dir;

        public Node(int y, int x, int weight, int speed, int dir) {
            this.y = y;
            this.x = x;
            this.weight = weight;
            this.speed = speed;
            this.dir = dir;
        }
    }
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine()," ");
        Function<String,Integer> stoi = Integer::parseInt;
        int n = stoi.apply(st.nextToken());
        int m = stoi.apply(st.nextToken());
        int k = stoi.apply(st.nextToken());

        Queue<Node> input = new LinkedList<>();
        for(int i = 0 ; i < m ; i++){
            st = new StringTokenizer(br.readLine()," ");
            int y = stoi.apply(st.nextToken())-1;
            int x = stoi.apply(st.nextToken())-1;
            int weight = stoi.apply(st.nextToken());
            int dir = stoi.apply(st.nextToken());
            int speed = stoi.apply(st.nextToken());
            input.offer(new Node(y,x,weight,dir,speed));
        }
        for(int i = 0 ; i < k ; i++){
            move(input,n);
        }
        int weightSum = 0;
        while(!input.isEmpty()){
            weightSum += input.poll().weight;
        }
        System.out.println(weightSum);
    }
    private static List<Node>[][] initMap(int n){
        List<Node>[][]map = new List[n][n];
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ; j < n ; j++){
                map[i][j] = new ArrayList<Node>();
            }
        }
        return map;
    }
    private static void move(Queue<Node> input, int n) {
        List<Node>[][] map = initMap(n);
        List<Node>nextInput = new ArrayList<>();
        while(!input.isEmpty()){
            moveFire(input.poll(),map,n);
        }
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ; j < n ; j++){
                if(map[i][j].size() > 1){
                    conflict(i,j,map,input);
                }else if(map[i][j].size() == 1){
                    input.offer(map[i][j].get(0));
                }
            }
        }
    }

    private static void conflict(int y, int x, List<Node>[][] map, Queue<Node> input) {
        int weightSum = 0;
        int speedSum = 0;
        int size = map[y][x].size();
        int remainder = 0;
        boolean flag = true;
        for(int i = 0 ; i < map[y][x].size() ; i++){
            Node node = map[y][x].get(i);
            weightSum += node.weight;
            speedSum += node.speed;
            if(i == 0){
                remainder = node.dir % 2;
            }else if(flag){
                if(remainder != node.dir % 2){
                    flag = false;
                }
            }
        }
        if(weightSum /5 == 0){
            return;
        }
        for(int i = 0 ; i < 4 ; i++){
            int dir = 2*i;
            if (!flag) {
                dir += 1;
            }
            input.offer(new Node(y,x,weightSum/5,speedSum/size,dir));
        }
    }

    private static final int[] dy = {-1,-1,0,1,1,1,0,-1};
    private static final int[] dx = {0,1,1,1,0,-1,-1,-1};
    private static void moveFire(Node node,  List<Node>[][] map, int n) {
        int ny = (node.y + dy[node.dir] * node.speed + n * node.speed) % n;
        int nx = (node.x + dx[node.dir] * node.speed + n * node.speed) % n;
        map[ny][nx].add(new Node(ny,nx,node.weight, node.speed, node.dir));
    }
}