경계값 넘어설떄 오버플로우/언더플로우값 처리 방법은 아래 링크참고
[JAVA] 백준 마법사 상어와 파이어볼
이틀만에 성공했다... grid는 x,y를 row col을 이처럼 적용해야된다. 보통 (r,c)로 주어지니 (y,x)로 받아야한다!! 우선 아래 코드에서는 x,y값을 반대로 적용했다. 그래서 문제 푸는내내 계속 헷갈렸다.
skmouse.tistory.com
구현문제였다.
(소요시간 : 2시간)
단순 구현문제였는데, N값의 경계값을 넘어가는 방식에 대해서 수학적으로 고민하다가 시간이 많이 흘렀다.
위 방법을 숙지해놓는것이 도움이 될 것같다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int N, M;
static int[][] a;
static int[] d, s;
static int[] dirR = {0,0, -1, -1, -1, 0, 1, 1, 1};
static int[] dirC = {0,-1, -1, 0, 1, 1, 1, 0, -1};
static Deque<Cloud> clouds = new LinkedList<>();
static Deque<Cloud> REMOVEDclouds = new LinkedList<>();
static class Cloud {
int r, c;
Cloud(int r, int c) {
this.r = r;
this.c = c;
}
void move(int d, int s) {
r = r+ (s%N) * dirR[d];
c = c +(s%N) * dirC[d];
if (r > N) r = r % N;//업오버플로우
if (r < 1) r = N - Math.abs(r);//다운오버플로우
if (c > N) c = c % N;//업오버플로우
if (c < 1) c = N - Math.abs(c);//다운오버플로우
}
}
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());
a = new int[N + 1][N + 1];
d = new int[M];
s = new int[M];
for (int r = 1; r <= N; r++) {
st = new StringTokenizer(br.readLine());
for (int c = 1; c <= N; c++) {
a[r][c] = Integer.parseInt(st.nextToken());
}
}
for (int m = 0; m < M; m++) {
st = new StringTokenizer(br.readLine());
d[m] = Integer.parseInt(st.nextToken());
s[m] = Integer.parseInt(st.nextToken());
}
//(N, 1), (N, 2), (N-1, 1), (N-1, 2)에 비구름이 생긴다.
clouds.add(new Cloud(N, 1));
clouds.add(new Cloud(N, 2));
clouds.add(new Cloud(N - 1, 1));
clouds.add(new Cloud(N - 1, 2));
for (int m = 0; m < M; m++) {
moves(d[m], s[m]);
}
int sum=0;
for(int r=1; r<=N; r++) {
for (int c = 1; c <= N; c++) {
sum+=a[r][c];
}
}
System.out.println(sum);
}
static int[][] nonRC;
static void moves(int d, int s) {
int size = clouds.size();
for (int sz = 0; sz < size; sz++) {
Cloud cld = clouds.remove();
cld.move(d, s);
a[cld.r][cld.c]++;
REMOVEDclouds.add(cld);
}
int rdsize = REMOVEDclouds.size();
nonRC = new int[rdsize][2];
for (int rsz = 0; rsz < rdsize; rsz++) {
Cloud cld = REMOVEDclouds.remove();
waterCheck(cld.r, cld.c);
nonRC[rsz][0] = cld.r;
nonRC[rsz][1] = cld.c;
}
for (int r = 1; r <= N; r++) {
for (int c = 1; c <= N; c++) {
boolean checker = false;
checker = notRemovedLoc(r, c);
if (a[r][c] >= 2 && checker) {
a[r][c] -= 2;
clouds.add(new Cloud(r, c));
}
}
}
}
static boolean notRemovedLoc(int r, int c) {
for (int[] rc : nonRC)
if (rc[0] == r && rc[1] == c) return false;//전에 건드렸던 구름이라면 거짓
return true;
}
static void waterCheck(int r, int c) {
int count = 0;
//왼위
int checkR = r - 1;
int checkC = c - 1;
if (boundaryCheck(checkR, checkC)) count++;
//오위
checkR = r - 1;
checkC = c + 1;
if (boundaryCheck(checkR, checkC)) count++;
//왼아래
checkR = r + 1;
checkC = c - 1;
if (boundaryCheck(checkR, checkC)) count++;
//오른아래
checkR = r + 1;
checkC = c + 1;
if (boundaryCheck(checkR, checkC)) count++;
a[r][c] += count;
}
static boolean boundaryCheck(int r, int c) {
if (r > 0 && c > 0 && r <= N && c <= N) {
return a[r][c] >= 1;
}
return false;
}
}
반응형
'코딩테스트 > Java' 카테고리의 다른 글
[JAVA] 백준 경사로 (0) | 2021.09.28 |
---|---|
(2021 카카오) 합승 택시 요금 JAVA (0) | 2021.09.24 |
[JAVA] 백준 사다리 조작 (0) | 2021.09.16 |
(2021 카카오) 광고삽입 JAVA (0) | 2021.09.11 |
[JAVA] 백준 주사위 윷놀이 (0) | 2021.09.01 |