티스토리 뷰
https://www.acmicpc.net/problem/21610
21610번: 마법사 상어와 비바라기
마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기
www.acmicpc.net
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main_BOJ_21610 {
static int N, M;
static int[][] map;
static ArrayList<int[]> clouds=new ArrayList<>();
static boolean[][] visited;
static int[] dr= {0, -1, -1, -1, 0, 1, 1, 1};
static int[] dc= {-1, -1, 0, 1, 1, 1, 0, -1};
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());
map=new int[N][N];
visited=new boolean[N][N];
for (int i=0; i<N; i++) {
st=new StringTokenizer(br.readLine());
for (int j=0; j<N; j++){
map[i][j]=Integer.parseInt(st.nextToken());
}
}
int[][] initials= {{N-1,0}, {N-1, 1}, {N-2, 0}, {N-2, 1}};
for (int i=0; i<4; i++) {
clouds.add(initials[i]);
}
for (int i=0; i<8; i++) {
if (dr[i]<0) dr[i]=(N-1);
if (dc[i]<0) dc[i]=(N-1);
}
for (int i=0; i<M; i++) {
st=new StringTokenizer(br.readLine());
int d=Integer.parseInt(st.nextToken())-1;
int s=Integer.parseInt(st.nextToken());
move(d, s);
increment();
copy();
clouds.clear();
process();
}
int answer=0;
for (int i=0; i<N; i++) {
for (int j=0; j<N; j++) {
answer+=map[i][j];
}
}
System.out.println(answer);
}
private static void move(int d, int s) {
int nr, nc;
for (int i=0; i<clouds.size(); i++) {
nr=clouds.get(i)[0];
nc=clouds.get(i)[1];
if (d%2==0) s=s%N;
for (int j=0; j<s; j++) {
nr=(nr+dr[d])%N;
nc=(nc+dc[d])%N;
}
clouds.set(i, new int[] {nr,nc});
}
}
private static void increment() {
int r, c;
for (int i=0; i<N; i++) {
Arrays.fill(visited[i], false);
}
for (int i=0; i<clouds.size(); i++) {
r=clouds.get(i)[0];
c=clouds.get(i)[1];
map[r][c]++;
visited[r][c]=true;
}
}
private static void copy() {
int[] diagonal_r= {-1,-1,1,1};
int[] diagonal_c= {-1,1,1,-1};
int r, c, nr, nc;
for (int i=0; i<clouds.size(); i++) {
int cnt=0;
r=clouds.get(i)[0];
c=clouds.get(i)[1];
for (int j=0; j<4; j++) {
nr=r+diagonal_r[j];
nc=c+diagonal_c[j];
if (nr<0 || nc<0 || nr>=N || nc>=N || map[nr][nc]==0) continue;
cnt++;
}
map[r][c]+=cnt;
}
}
private static void process() {
for (int i=0; i<N; i++) {
for (int j=0; j<N; j++) {
if (map[i][j]>=2 && !visited[i][j]) {
map[i][j]-=2;
clouds.add(new int[] {i,j});
}
}
}
}
}
시뮬레이션 문제
문제의 조건에 맞게 구현해주면 된다.
현재 구름의 위치를 ArrayList에 저장하고, 현재 구름이 위치한 공간을 visited 배열로 표현했다.
다만 구름을 움직일 때 주의할 점은 1번째 행, 열이 N번째 행, 열과 서로 이어져 있다는 점이다.
이것을 움직일 때 고려해 주기 위해 현재 위치에서 -1만큼 움직이는 것에 대해, N-1 번을 움직이는 것으로 모두 바꿔주었다. (현재 위치+N-1)%N 해주면 현재 위치보다 -1 만큼 움직이는 거리가 나오기 때문이다.
다른 분들의 코드를 보니 이렇게 복잡하게? 할 필요 없고, (이렇게 바꿔준다면 4번 대각선 체크에서 또 delta 배열을 새로 만들어줘야 한다)
좌표를 움직여 가면서 만약 좌표가 0 미만이 되면 N-1 로 그 좌표를 바꿔주고
N 이상이 되면 0으로 그 좌표를 바꿔주는 형태로 진행을 했다.
'Problem Solving' 카테고리의 다른 글
[BOJ 23288] 주사위 굴리기 2 (Java) (0) | 2022.04.21 |
---|---|
[BOJ 20061] 모노미노도미노2 (Java) (0) | 2022.04.21 |
[BOJ 1520] 내리막 길 (Java) (0) | 2022.04.18 |
[BOJ 1005] ACM Craft (Java) (0) | 2022.04.15 |
[BOJ 1941] 소문난 칠공주 (Java) (0) | 2022.04.14 |