티스토리 뷰
https://www.acmicpc.net/problem/20056
20056번: 마법사 상어와 파이어볼
첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치
www.acmicpc.net
풀이
문제에서 주어진 대로 진행한다.
1) 클래스 FireBall 을 생성. (좌표, 질량, 뱡향, 속력을 담을 용도), 파이어볼의 갯수를 담을 map[][] 생성
2) List에 입력받은 M개의 FireBall 들을 담는다. map[r][c]++
3) 모든 파이어볼을 이동시킨다. map[r][c]--, map[nr][nc]++
4) 파이어볼이 2개 이상 있으면 합치고 질량, 속력, 방향을 할당함. <- 상당히 귀찮다.
5) 이때 질량이 0이 되면 해당 파이어볼을 없애버린다.
6) list를 탐색하며 모든 질량을 더한값을 출력
주의사항
1) 입력이 1부터 시작함.
2) 이동시 범위 밖으로 나가는 경우 반대쪽에서 튀어나오는 처리를 잘 해줘야함
3) list를 탐색할때 list.remove(i)를 할 경우 i-- 도 같이 해줘야한다.
4) 방향 순서 중요
package com.baekJoon;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
public class BJ_G5_20056_마법사상어와파이어볼 {
static BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokens;
static int N,M,K,map[][];
static List<FireBall> list = new ArrayList<>();
public static void main(String[] args) throws NumberFormatException, IOException {
input = new BufferedReader(new StringReader(src));
tokens = new StringTokenizer(input.readLine());
N = Integer.parseInt(tokens.nextToken());
M = Integer.parseInt(tokens.nextToken());
K = Integer.parseInt(tokens.nextToken());
map = new int[N][N];
for(int i=0; i<M; i++) {
tokens = new StringTokenizer(input.readLine());
int r = Integer.parseInt(tokens.nextToken())-1;
int c = Integer.parseInt(tokens.nextToken())-1;
int m = Integer.parseInt(tokens.nextToken());
int s = Integer.parseInt(tokens.nextToken());
int d = Integer.parseInt(tokens.nextToken());
list.add(new FireBall(r, c, m, s, d));
map[r][c] = 1;
}
// for(int x[] : map) {
// System.out.println(Arrays.toString(x));
// }
// System.out.println(list);
for(int k=0; k<K; k++) {
move();
}
int answer = 0;
for(int i=0; i<list.size(); i++) {
answer += list.get(i).m;
}
System.out.println(answer);
}
private static void move() {
for(int i=0; i<list.size(); i++) {
FireBall front = list.get(i);
int nr = (front.r + N + ((front.s % N) * dr[front.d]))%N;
int nc = (front.c + N + ((front.s % N) * dc[front.d]))%N;
map[front.r][front.c]--;
map[nr][nc]++;
list.get(i).r = nr;
list.get(i).c = nc;
}
for(int r=0; r<N; r++) {
for(int c=0; c<N; c++) {
if(map[r][c] > 1) {
combine(r,c,map[r][c]);
}
}
}
// System.out.println();
// for(int x[] : map) {
// System.out.println(Arrays.toString(x));
// }
// System.out.println(list);
}
private static void combine(int r, int c, int cnt) { //cnt 는 겹친 파이어볼의 개수
int sumM = 0;
int sumS = 0;
int temp = -1;
boolean flag = false; // 방향이 일관성 없는지 확인하는 변수
for(int i=0; i<list.size(); i++) {
if(list.get(i).r == r && list.get(i).c == c) {
sumM += list.get(i).m;
sumS += list.get(i).s;
if(!flag) {
if(temp == -1) {
temp = list.get(i).d % 2;
}else if(temp != list.get(i).d%2) {
flag = true;
}
}
list.remove(i);
i--; // 리스트에서 하나 빠졌으니 i도 줄여 줘야함
}
}
sumM = sumM / 5;
sumS = sumS / cnt;
if(sumM > 0) { // 질량이 0 이상이어야 함
map[r][c] = 4;
if(!flag) { // 합쳐지는 파이어볼의 방향이 모두 홀수이거나 모두 짝수인 경우
// 방향은 0,2,4,6
for(int d=0; d<7; d+=2) {
list.add(new FireBall(r, c, sumM, sumS, d));
} // 파이어볼의 방향이 제각각인 경우
}else {
// 방향은 1,3,5,7
for(int d=1; d<8; d+=2) {
list.add(new FireBall(r, c, sumM, sumS, d));
}
}
}else {
map[r][c] = 0;
}
}
static class FireBall{
int r;
int c;
int m;
int s;
int d;
public FireBall(int r, int c, int m, int s, int d) {
super();
this.r = r;
this.c = c;
this.m = m;
this.s = s;
this.d = d;
}
@Override
public String toString() {
return "FireBall [r=" + r + ", c=" + c + ", m=" + m + ", s=" + s + ", d=" + d + "]";
}
}
static int dr[] = {-1,-1,0,1,1,1,0,-1}; // 8 방향. 순서 중요함.
static int dc[] = {0,1,1,1,0,-1,-1,-1};
static String src =
"4 2 3\r\n"
+ "1 1 5 2 2\r\n"
+ "1 4 7 1 6";
}

후기
아주 질긴 문제다. 난이도에 전혀 영향을 끼치지 않으면서 그저 귀찮음만을 증가시킬 목적을 지닌 여러 조건들에서 출제자의 못된 심보가 느껴진다.
'Algorithm' 카테고리의 다른 글
[백준] G5 14719 빗물 (java) (0) | 2021.07.29 |
---|---|
[백준] G5 2174 로봇 시뮬레이션 (ja) (0) | 2021.07.29 |
[백준] G4 15684 사다리 조작 (java) (0) | 2021.07.29 |
[백준] G5 21610 마법사 상어와 비바라기 (java) (0) | 2021.07.29 |
[백준] G5 1091 카드 섞기 (java) (0) | 2021.07.29 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 자바
- java
- react
- 현꾸라지
- map
- 리액트 네이티브
- S2
- S3
- 코딩새내기
- 백준
- 다익스트라
- g4
- 백트래킹
- Spring Boot
- react native
- 리액트
- BFS
- 객체지향
- 우선순위큐
- 그리디
- DFS
- G5
- Spring
- 구현
- 알고리즘
- SWEA
- 문자열
- PriorityQueue
- laugh4mile
- 시뮬레이션
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함