[BOJ 17144] 미세먼지 안녕
업데이트:
문제
- BOJ 17144
- 문제의 저작권은 Baekjoon Online Judge에 있습니다.
접근방식
한달전 쯤 풀었었는데 스터디를 하면서 한번 더 풀어본 문제이다.
그래서인지 쉽게 생각할 수 있었고 코드도 이전에 비해 더 간결해졌다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main{
static int R,C,T;
static int[][] map;
static int[][] copy;
static int[] di = {-1, 0, 1, 0}; //북동남서
static int[] dj = {0, 1, 0, -1};
static int r; //공기청정기 윗행 좌표
static int Ans;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
T = Integer.parseInt(st.nextToken());
map = new int[R][C];
for(int i=0; i<R; i++){
st = new StringTokenizer(br.readLine());
for(int j=0; j<C; j++){
map[i][j] = Integer.parseInt(st.nextToken());
if(map[i][j]==-1 && r==0) r = i;
}
}//Input map
int t = 0;
while(++t<=T){
//1. 확산
spread();
//2. 공기청정기 작동
clean();
}
//출력
for(int i=0; i<R; i++){
for(int j=0; j<C; j++){
if(map[i][j] == -1) continue;
Ans += map[i][j];
}
}
System.out.println(Ans);
}
private static void clean() {
//1. 반시계방향: 들어가는 쪽 공백부터 => 남서북동
for(int i=r-1; i>0; i--) map[i][0] = map[i-1][0];
for(int j=0; j<C-1; j++) map[0][j] = map[0][j+1];
for(int i=0; i<r; i++) map[i][C-1] = map[i+1][C-1];
for(int j=C-1; j>1; j--) map[r][j] = map[r][j-1];
map[r][1] = 0; //나오는쪽 0
//2. 시계방향: 들어가는 쪽 공백부터 => 북서남동
r++; //공기청정기 아래행
for(int i=r+1; i<R-1; i++) map[i][0] = map[i+1][0];
for(int j=0; j<C-1; j++) map[R-1][j] = map[R-1][j+1];
for(int i=R-1; i>r; i--) map[i][C-1] = map[i-1][C-1];
for(int j=C-1; j>1; j--) map[r][j] = map[r][j-1];
map[r][1] = 0;
r--; //다시 윗행
}
private static void spread() {
copy = new int[R][C];
copy[r][0] = -1;//공기청정기 표시
copy[r+1][0] = -1;
for(int i=0; i<R; i++){
for(int j=0; j<C; j++){
if(map[i][j]>0){ //미세먼지가 있으면
int cnt = 0; //확산횟수
for(int d=0; d<4; d++){ //4방향 탐색
int ni = i+di[d];
int nj = j+dj[d];
//확산할 수 있는지 체크
if(ni>=0 && ni<R && nj>=0 && nj<C && map[ni][nj]!=-1){
copy[ni][nj] += map[i][j]/5;
cnt++;
}
}
//현재 좌표에서 남은 양 계산
copy[i][j] += map[i][j]-(map[i][j]/5)*cnt;
}
}
}//End 확산
//copy를 map으로
for(int i=0; i<R; i++){
for(int j=0; j<C; j++){
map[i][j] = copy[i][j];
}
}
}
}