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));
}
}
'알고리즘' 카테고리의 다른 글
백준 15684번 사다리 조작 (JAVA) (0) | 2022.03.30 |
---|---|
백준 20057번 마법사 상어와 토네이도 (JAVA) (0) | 2022.03.29 |
백준 2174번 로봇 시뮬레이션 (JAVA) (0) | 2022.03.27 |
백준 19236번 청소년 상어(JAVA) (0) | 2022.03.26 |
백준 17779번 게리맨더링2 (JAVA) (0) | 2022.03.25 |