반응형
17144번: 미세먼지 안녕!
미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사
www.acmicpc.net
문제 이해 |
공기청정기는 항상 1번 열에 설치되어 있고, 크기는 두 행을 차지한다. 공기청정기가 설치되어 있지 않은 칸에는 미세먼지가 있고, (r, c)에 있는 미세먼지의 양은 Ar,c이다. 1초 동안 아래 적힌 일이 순서대로 일어난다.
|
아이디어 |
- 시뮬레이션 문제. - 그냥 하라는데로 따라서 쭈욱 코드를 짰다. - 클래스를 하나 따로 빼서 먼지의 좌표값, 먼지크기를 넣어줬다. |
먼지를 넣을 클래스 |
static class Pos {
int x, y, w;
public Pos(int x, int y, int w) {
this.x = x;
this.y = y;
this.w = w;
}
}
입력 구간 |
입력받을 때 미리 공청기 위치랑 먼지 위치를 받아놨다.
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];
dusts = new ArrayList<>();
ac = new ArrayList<>();
check = 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] == airCleaner) {
ac.add(new Pos(i, j,map[i][j])); // 공청기 위치를 담는다.
}
else if (map[i][j] > 0) {
dusts.add(new Pos(i, j,map[i][j]));// 미세먼지위치를 담는다.
}
}
}
먼지 찾아서 출력하기 |
int ans = 0;
// T초 동안 시행한다.
for (int i = 0; i < T; ++i) {
// 1. 미세먼지가 확산된다. 확산은 미세먼지가 있는 모든 칸에서 동시에 일어난다
moveDust();
// 2. 공청기가 작동한다.
actAirCleaner();
// 3. dusts 리스트를 갱신한다.
ans = updateDustsPosandSum();
}
System.out.println(ans);
미세먼지 확산시키기 |
private static void moveDust() {
for (Pos dust : dusts) {
int cnt = 0;// 확산된 개수
int val = dust.w;//미세먼지크기
int spread = val/5;//확산 미세먼지 크기
for (int d = 0; d < 4; ++d) {
int nx = dust.x + dx[d];
int ny = dust.y + dy[d];
if(isInArea(nx, ny) && map[nx][ny] != airCleaner) { // 영역안이고, 공청기아니면
map[nx][ny] += spread; // 확산해주고
cnt++; // 카운트
}
}
map[dust.x][dust.y] -= (val/5) * cnt; // 새로운 값으로 갱신
}
}
공청기 작동시키기 (윗부분은 반시계, 아랫부분은 시계) |
private static void actAirCleaner() {
// upper ac[0]
Pos upper = ac.get(0);
// 0,0 -> upper.x - 1, upper.y 까지 내린다.
for(int i= upper.x-1; i > 0 ; --i) map[i][0] = map[i-1][0];
// 0,C-1 -> 0,0 까지
for(int j=0; j<C-1; ++j) map[0][j]=map[0][j+1];
// upper.x , C-1 -> 0,C-1까지
for(int i=0;i<upper.x;++i) map[i][C-1] = map[i+1][C-1];
// upper.x, upper.y -> upper.x, C-1 까지
for(int j=C-1;j > upper.y+1;--j) map[upper.x][j] = map[upper.x][j-1];
map[upper.x][upper.y+1] = 0;
// lower ac[1]
Pos lower = ac.get(1);
// lower.x+1,0 -> R-1,0
for(int i=lower.x+1;i<R-1;++i) map[i][0]=map[i+1][0];
// R-1,0 -> R-1,C-1 o
for(int j=0; j<C-1;++j) map[R-1][j] = map[R-1][j+1];
// R-1,C-1 -> lower.x +1, C-1 o
for(int i=R-1; i>lower.x;--i) map[i][C-1] =map[i-1][C-1];
// lower.x, C-1 -> lower.x, lower.y_1
for(int j=C-1; j>lower.y+1; --j) map[lower.x][j]=map[lower.x][j-1];
map[lower.x][lower.y+1] = 0;
}
미세먼지 총합이랑 미세먼지 위치 등록하기 |
private static int updateDustsPosandSum() {
dusts = new ArrayList<>();
int sum = 0;
for(int i=0;i<R;++i) {
for(int j=0;j<C;++j) {
if(map[i][j] > 0) {
dusts.add(new Pos(i,j,map[i][j]));
sum += map[i][j];
check[i][j] = 1;
}
}
}
return sum;
}
코드 |
import java.io.*;
import java.util.*;
public class Main {
static class Pos {
int x, y, w;
public Pos(int x, int y, int w) {
this.x = x;
this.y = y;
this.w = w;
}
}
static int R, C, T, map[][];
static final int airCleaner = -1;
static int[] dx = { -1, 1, 0, 0 };
static int[] dy = { 0, 0, -1, 1 };
static ArrayList<Pos> ac;
static ArrayList<Pos> dusts;
static int[][] check;
public static void main(String[] args) throws Exception {
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];
dusts = new ArrayList<>();
ac = new ArrayList<>();
check = 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] == airCleaner) {
ac.add(new Pos(i, j,map[i][j])); // 공청기 위치를 담는다.
}
else if (map[i][j] > 0) {
dusts.add(new Pos(i, j,map[i][j]));// 미세먼지위치를 담는다.
}
}
}
int ans = 0;
// T초 동안 시행한다.
for (int i = 0; i < T; ++i) {
// 1. 미세먼지가 확산된다. 확산은 미세먼지가 있는 모든 칸에서 동시에 일어난다
moveDust();
// 2. 공청기가 작동한다.
actAirCleaner();
// 3. dusts 리스트를 갱신한다.
ans = updateDustsPosandSum();
}
System.out.println(ans);
}
private static int updateDustsPosandSum() {
dusts = new ArrayList<>();
int sum = 0;
for(int i=0;i<R;++i) {
for(int j=0;j<C;++j) {
if(map[i][j] > 0) {
dusts.add(new Pos(i,j,map[i][j]));
sum += map[i][j];
check[i][j] = 1;
}
}
}
return sum;
}
private static void actAirCleaner() {
// upper ac[0]
Pos upper = ac.get(0);
// 0,0 -> upper.x - 1, upper.y 까지 내린다.
for(int i= upper.x-1; i > 0 ; --i) map[i][0] = map[i-1][0];
// 0,C-1 -> 0,0 까지
for(int j=0; j<C-1; ++j) map[0][j]=map[0][j+1];
// upper.x , C-1 -> 0,C-1까지
for(int i=0;i<upper.x;++i) map[i][C-1] = map[i+1][C-1];
// upper.x, upper.y -> upper.x, C-1 까지
for(int j=C-1;j > upper.y+1;--j) map[upper.x][j] = map[upper.x][j-1];
map[upper.x][upper.y+1] = 0;
// lower ac[1]
Pos lower = ac.get(1);
// lower.x+1,0 -> R-1,0
for(int i=lower.x+1;i<R-1;++i) map[i][0]=map[i+1][0];
// R-1,0 -> R-1,C-1 o
for(int j=0; j<C-1;++j) map[R-1][j] = map[R-1][j+1];
// R-1,C-1 -> lower.x +1, C-1 o
for(int i=R-1; i>lower.x;--i) map[i][C-1] =map[i-1][C-1];
// lower.x, C-1 -> lower.x, lower.y_1
for(int j=C-1; j>lower.y+1; --j) map[lower.x][j]=map[lower.x][j-1];
map[lower.x][lower.y+1] = 0;
}
private static void moveDust() {
for (Pos dust : dusts) {
int cnt = 0;
int val = dust.w;
int spread = val/5;
for (int d = 0; d < 4; ++d) {
int nx = dust.x + dx[d];
int ny = dust.y + dy[d];
if(isInArea(nx, ny) && map[nx][ny] != airCleaner) { // 영역안이고, 공청기아니면
map[nx][ny] += spread; // 확산해주고
cnt++; // 카운트
}
}
map[dust.x][dust.y] -= (val/5) * cnt;
}
}
static boolean isInArea(int x, int y) {
return 0 <= x && x < R && 0 <= y && y < C;
}
}
집사는개발자가되고파
choppadontbiteme.tistory.com
반응형
'Algorithm > BOJ' 카테고리의 다른 글
[ BOJ ] 10820 문자열 분석 B2 (JAVA) (0) | 2021.08.07 |
---|---|
[ BOJ ] 1009. 분산처리 B3 (JAVA) (0) | 2021.04.20 |
[ BOJ ] 17471. 게리맨더링 G5 JAVA (0) | 2021.04.16 |
[ BOJ ] 2564. 경비원 S1 JAVA (0) | 2021.04.16 |
[ BOJ ] 16562. 친구비 G3 JAVA (0) | 2021.04.15 |