티스토리 뷰
1. 문제
https://www.acmicpc.net/problem/20056
20056번: 마법사 상어와 파이어볼
첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치
www.acmicpc.net
2. 문제 풀이 겸 회고
구현 넘 재밌는데..... 와... 이번에 파이어볼 방향 별로 옮겨줄 때 애먹었다...(시뮬 미워..) ㅜ0ㅜ
그 부분만 아니면 1시간 컷 했을 듯.... ;-;
[문제 설명]
문제를 보면 파이어볼 옮겨서 파이어볼 분해되고 합치고 이런 과정이 반복된다.
시뮬(반복해서 돌려주고) 과 구현(조건에 맞춰 구현)의 조합
문제의 파이어볼 위치값 이동부분이다.
이부분에서 한 3시간 날려먹은 듯... 시롸냐....
0 1 2 3 0 1 2 3 0 1 2 3 (이런 식으로 맵 index가 연달아 있음 -> 행, 열 둘 다)
처음에는 그냥 case 문으로 하나씩 조건에 맞춰서 넣어주려고 했다.. 하지만 이건 너무 반복되는 부분도 많고 그래서 지웠다.
또한... 계속 IndexOutOfBoundsException 나고.. 막 값이 이상한 데에 들어가고 그래서 방향 탐색으로 해줬다.
static int[] dr = { -1, -1, 0, 1, 1, 1, 0, -1 };
static int[] dc = { 0, 1, 1, 1, 0, -1, -1, -1 };
0~7번까지 방향을 의미한다.
int nr = cur.r + (dr[cur.d] * cur.s) % N;
int nc = cur.c + (dc[cur.d] * cur.s) % N;
이건 다음에 넣어줘야 할 파이어볼 위치를 구해줬다.
(여기서 cur은 Fireball의 정보가 담긴 객체를 의미하며, r과 c는 0부터 해주기 위해 맨 처음에 -1을 해줬음)
하지만 이렇게만 할 경우, nr, nc가 0보다 작거나 N-1보다 클 경우 IndexOutOfBoundsException 이놈이 나온다.
그래서 조건 추가!
if (nr < 0) {
nr = N + nr;
} else if (nr >= N) {
nr %= N;
}
if (nc < 0) {
nc = N + nc;
} else if (nc >= N) {
nc %= N;
}
이렇게 해줘서 방향 옮겨줬다.
또한, 여기서 바로 빼왔던 2차원배열에 바로 삽입하는 게 아니라 객체 list 하나 선언해서 그 안에 임시 보관해줬음
fbList.add(new Fireball(nr, nc, cur.m, cur.s, cur.d));
다 구해주면
임시 보관된 객체들 다시 2차원배열에 삽입시켜줌!
이렇게 Fireball 움직여주고, 그 후는 문제에서 원하는 조건으로 구현해줬음
각 위치에 있는 파이어볼 하나로 합친 다음에 질량이 5보다 작으면 (질량 / 5 =질량 0) 해당 구역은 pass 하고
클 경우에는 파이어볼 4개로 나눠서 (조건에 맞춰서) 넣어줬음
그럼 끗!
아마 많은 분들이 저기 파이어볼 이동 과정에서 애먹었을 듯 (나만 그럴 수도 ㅋㄷㅋㄷ)
3. 코드
package net.acmicpc.samsung;
import java.io.*;
import java.util.*;
public class Solution_20056_마법사상어와파이어볼 {
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) {
this.r = r;
this.c = c;
this.m = m;
this.s = s;
this.d = d;
}
}
static int N, M, K;
static ArrayList<Fireball> map[][];
static ArrayList<Fireball> fbList;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken()); // 맵크기
M = Integer.parseInt(st.nextToken()); // M개의 파이어볼 정보
K = Integer.parseInt(st.nextToken()); // K번 명령
map = new ArrayList[N][N];
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
map[r][c] = new ArrayList<Fireball>();
}
}
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int r = Integer.parseInt(st.nextToken()) - 1;
int c = Integer.parseInt(st.nextToken()) - 1;
map[r][c].add(new Fireball(r, c, Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()),Integer.parseInt(st.nextToken())));
}
while (K-- > 0) {
moveFireball();
}
int answer = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < map[i][j].size(); k++) {
answer += map[i][j].get(k).m;
}
}
}
System.out.println(answer);
}
private static void moveFireball() {
fbList = new ArrayList<>();
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
while (map[r][c].size() != 0) {
Fireball cur = map[r][c].remove(0);
selectDir(cur);
}
}
}
addMap(fbList);
divFireball();
}
static int[] dr = { -1, -1, 0, 1, 1, 1, 0, -1 };
static int[] dc = { 0, 1, 1, 1, 0, -1, -1, -1 };
private static void selectDir(Fireball cur) {
int nr = cur.r + (dr[cur.d] * cur.s) % N;
int nc = cur.c + (dc[cur.d] * cur.s) % N;
// System.out.println("====================");
// System.out.println(cur.r + " " + cur.c + " " + cur.d + " " + cur.s);
// System.out.println(nr + " " + nc);
if (nr < 0) {
nr = N + nr;
} else if (nr >= N) {
nr %= N;
}
if (nc < 0) {
nc = N + nc;
} else if (nc >= N) {
nc %= N;
}
fbList.add(new Fireball(nr, nc, cur.m, cur.s, cur.d));
}
private static void addMap(ArrayList<Fireball> tmpList) {
for (int i = 0; i < tmpList.size(); i++) {
Fireball cur = tmpList.get(i);
map[cur.r][cur.c].add(new Fireball(cur.r, cur.c, cur.m, cur.s, cur.d));
}
}
private static void divFireball() {
fbList = new ArrayList<>();
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (map[r][c].size() >= 2) {
int nm = 0; // 그 다음 질량
int ns = 0; // 그 다음 속도
int odd = 0; // 홀수 개수(방향)
int even = 0; // 짝수 개수(방향)
int len = map[r][c].size();
while (map[r][c].size() != 0) {
Fireball fb = map[r][c].remove(0);
nm += fb.m;
ns += fb.s;
if (fb.d % 2 == 0) {
even++;
} else {
odd++;
}
}
if (nm < 5)
continue;
else {
ns = ns / len;
if (even == len || odd == len) {
for (int i = 0; i < 4; i++) {
fbList.add(new Fireball(r, c, nm / 5, ns, i * 2));
}
} else {
for (int i = 0; i < 4; i++) {
fbList.add(new Fireball(r, c, nm / 5, ns, i * 2 + 1));
}
}
}
}
}
}
addMap(fbList);
}
//현재 맵 객체 궁금하시면, 주석 풀고 원하는 위치에 메서드 삽입해서 사용하세용~
// private static void print() {
// for (int i = 0; i < map.length; i++) {
// for (int j = 0; j < map[0].length; j++) {
// System.out.print(i + " " + j + ": ");
// for (int k = 0; k < map[i][j].size(); k++) {
// System.out.print(map[i][j].get(k).m + " ");
// }
// System.out.println();
// }
// System.out.println();
// }
// }
}
피드백은 언제나 환영입니다 :) 🌳
'algo > 백준' 카테고리의 다른 글
[백준] 18868_멀티버스 (JAVA) (2) | 2022.11.02 |
---|---|
[백준] 16234_인구이동 (JAVA) (0) | 2022.09.28 |
[백준] 11052_카드 구매하기 (JAVA) (0) | 2022.09.20 |
[백준] 1912_연속합 (JAVA) (0) | 2022.09.19 |
[백준] 20055_컨베이어 벨트 위의 로봇(JAVA) (2) | 2022.09.19 |
- Total
- Today
- Yesterday
- 정보통신산업진흥원
- 자바 return
- 프로그래머스 할인행사
- 18868 멀티버스 java
- 서울ICT이노베이션
- level2 롤케이크 자르기
- 할인행사 자바
- 마법사상어와 파이어볼
- NIPA
- AI캠프
- JAVA 할인행사
- 유데미
- AI-WEB 교육
- 메서드형 void
- JAVA 컬랙션
- Java 멀리 뛰기
- HashMap 자바
- 1개 Key 여러개 Value
- java 마법사 상어와 파이어볼
- AI교육
- java 멀티버스
- 멀리 뛰기 자바
- 백준 멀티버스 자바
- 플그 멀리 뛰기
- IT개발캠프
- 멀티버스 java
- 프로그래머스 롤케이크자르기
- 16234 마법사 상어와 파이어볼
- 백엔드
- 프론트엔드
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |