❓ 문제 - 백준 미세먼지 안녕! 17144번 - JAVA 풀이법
출처
(https://www.acmicpc.net/problem/17144)
📝 문제해결법
1. 이 문제는 구현으로 풀었다.
- air_1과 air_2에 미세먼지의 위치 행 값을 저장한다.
- 해당 시간만큼 미세먼지 확산 -> 공기청정기 가동을 반복적으로 수행한 뒤 각 영역에 먼지 값 총합을 더해서 출력한다.
- 미세먼지 확산은 moving 함수로 구현하였다. 미세먼지의 확산 구현의 포인트는 map_copy를 통해 확산된 양을 저장한 후 다시 그것을 map에 깊은 복사 해주는 것이다. (--> 동시에 먼지가 확산하기 때문이다!)
- 공기청정기 가동은 air_machine()이라는 메소드로 구현했다.
2. air_machine() 함수
- 공기청정기의 윗 부분은 공기가 반시계 방향으로 순환하고 밑 부분은 공기가 시계 방향으로 순환한다.
- 공기청정기 윗 부분을 구현할 때 먼지의 이동처리는 0,0부터 시작하여 오른쪽 -> 아래 - > 왼쪽 -> 위로 이동하면서 이동하는 방향칸의 값을 자기 값으로 당겨옴 처리한다. 한 방향으로 쭉 이동하다가 이동하지 말아야할 범위를 넘어가면 다시 돌아와서 다음방향으로 이동하도록 처리한다. 그 후 도착지점인 1, 0에 도착하면 원래 0,0에 있던 값인 temp를 넣어준다.
- 공기청정기 아래 부분을 구현할 때 먼지의 이동처리는 r-1, 0부터 시작하여 오른쪽 -> 위 - > 왼쪽 -> 아래로 이동하면서 이동하는 방향칸의 값을 자기 값으로 당겨옴 처리한다. 한 방향으로 쭉 이동하다가 이동하지 말아야할 범위를 넘어가면 다시 돌아와서 다음방향으로 이동하도록 처리한다. 그 후 도착지점인 r-2, 0에 도착하면 원래 r-1,0에 있던 값인 temp를 넣어준다.
- 이동할 때 공기청정기에 들어가는 값은 0이고 공기청정기에서 나오는 값도 0이므로 값 이동시 맞춰서 구현해준다.
💻 소스코드
// BOJ - 미세먼지 안녕(17144번)
// 구현
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main_17144 {
public static int r, c, t;
public static int[][] map;
// 동, 남, 서, 북
public static int[] dx = {0, 1, 0, -1};
public static int[] dy = {1, 0, -1, 0};
// 동- 북 - 서 - 남
public static int[] down_dir = {0, 3, 2, 1};
public static int air_1, air_2;
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];
boolean check = false;
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) {
map[i][j] = 0;
if(!check) {
air_1 = i;
check = true;
} else {
air_2 = i;
}
}
}
}
while(t-- > 0) {
// 미세먼지 확산
moving();
for(int i=0;i<r;i++) {
for(int j=0;j<c;j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
System.out.println();
// 공기청정기 가동
air_machine();
for(int i=0;i<r;i++) {
for(int j=0;j<c;j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
System.out.println();
}
int ans = 0;
for(int i=0;i<r;i++) {
for(int j=0;j<c;j++) {
ans += map[i][j];
}
}
System.out.println(ans);
}
public static void moving() {
int[][] map_copy = new int[r][c];
for(int i=0;i<r;i++) {
map_copy[i] = map[i].clone();
}
for(int i=0;i<r;i++) {
for(int j=0;j<c;j++) {
int cnt = 0;
if(map[i][j] == 0) continue;
for(int d=0;d<4;d++) {
int nx = i + dx[d];
int ny = j + dy[d];
if(ny==0 && (nx==air_1 || nx == air_2)) {
continue;
}
if(0 <= nx && nx < r && 0 <= ny && ny < c) {
cnt++;
map_copy[nx][ny] += map[i][j] / 5;
}
}
map_copy[i][j] -= (map[i][j] / 5) * cnt;
}
}
for(int i=0;i<r;i++) {
map[i] = map_copy[i].clone();
}
}
public static void air_machine() {
// 반시계
int temp = map[0][0];
int x = 0;
int y = 0;
for(int d=0;d<4;d++) {
while (true) {
if(x==1 && y == 0) break;
int nx = x + dx[d];
int ny = y + dy[d];
if(ny < 0 || ny >= c || nx < 0 || nx >= air_2) {
break;
}
if(!(y == 0 && (x == air_1 || x == air_2))) {
map[x][y] = map[nx][ny];
}
x = nx;
y = ny;
}
}
map[1][0] = temp;
// 시계
temp = map[r-1][0];
x = r-1;
y = 0;
for(int d=0;d<4;d++) {
while (true) {
if(x==(r-2) && y==0) break;
int nx = x + dx[down_dir[d]];
int ny = y + dy[down_dir[d]];
if(ny < 0 || ny >= c || nx <= air_1 || nx >= r) {
break;
}
if(!(y == 0 && (x == air_1 || x == air_2))) {
map[x][y] = map[nx][ny];
}
x = nx;
y = ny;
}
}
map[r-2][0] = temp;
}
}
'알고리즘 > 알고리즘문풀' 카테고리의 다른 글
BOJ - 이차원 배열과 연산 17140번 (JAVA) (0) | 2022.04.29 |
---|---|
BOJ - 낚시왕 17143번 (JAVA) (0) | 2022.04.29 |
BOJ - 아기 상어 16236번 (JAVA) (0) | 2022.04.29 |
BOJ - 인구 이동 16234번 (JAVA) (0) | 2022.04.29 |
BOJ - 나무 재테크 16235번 (JAVA) (0) | 2022.04.22 |