Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- docker-compose
- 백트래킹
- 트리
- spring cloud
- 메모이제이션
- BFS
- 플로이드 와샬
- Logback
- Spring Cloud Config
- 주울
- 도커
- 유레카
- 스택
- 이분 탐색
- 구현
- dp
- 게이트웨이
- 구간 트리
- 서비스 디스커버리
- ZuulFilter
- 비트마스킹
- Gradle
- 다익스트라
- 스프링 시큐리티
- 달팽이
- Zuul
- 이분 매칭
- Java
- spring boot
- 완전 탐색
Archives
- Today
- Total
Hello, Freakin world!
[백준 17144번][Java] 미세먼지 안녕! 본문
구현 문제입니다.
중요한 구현 포인트는 두 가지입니다.
1. 미세먼지 확산
2. 바람 방향으로 먼지 이동시키기
1번은 그리 어렵지 않습니다.
동시에 모두 확산해야하므로 임시 배열 하나를 생성해 확산 결과를 통합해주고, 원래 배열에 덮어쓰면 해결
2번은 어떻게 구현하느냐에 따라 꽤 헤깔릴 수 있습니다.
변수 설정하고 값 저장했다가 다시 옮기고...
이런 과정들이 너무 짜증나서 저는 경로를 쭉 따라가 deque에 저장하고 요소들을 이동시켜 준 다음, 다시 경로에 그리는 방식으로 해결했습니다.
이 과정에도 코드를 정리하지 않으면 꽤 복잡해지는데, 함수형 인터페이스가 큰 도움이 됐네요.
Consumer2 라는 인수 두 개짜리 함수형 인터페이스를 선언해서 이용한 점도 포인트입니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.StringTokenizer;
/*
미세먼지 안녕!
*/
public class Main {
static int R,C,T;
static int[][] room;
public static void main(String[] args) throws IOException {
// BufferedReader br = new BufferedReader(new FileReader("testcase.txt"));
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());
room = new int[R][C];
for (int i = 0; i < R; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < C; j++) {
room[i][j] = Integer.parseInt(st.nextToken());
}
}
//확산 사이클
for (int i = 0; i < T; i++) {
spreadDust();
blowWind();
}
int totalDustAmount = getDustAmount(room);
System.out.println(totalDustAmount);
}
private static void spreadDust() {
int[][] dustMap = new int[R][C];
// dustMap에 확산상태 기록
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
spreadPossibleDirection(i, j, dustMap);
}
}
//room에 옮김
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (room[i][j] != -1) {
room[i][j] = dustMap[i][j];
}
}
}
}
private static void spreadPossibleDirection(int dustR, int dustC, int[][] dustMap) {
int[] dr = {0,0,1,-1};
int[] dc = {1,-1,0,0};
int possibleDirectionCount = 0;
for (int i = 0; i < 4; i++) {
int nextDustR = dustR + dr[i]; int nextDustC = dustC + dc[i];
if(isValid(nextDustR, nextDustC) && room[nextDustR][nextDustC] != -1 && room[dustR][dustC] >= 5) {
possibleDirectionCount++;
dustMap[nextDustR][nextDustC] += room[dustR][dustC]/5;
}
}
int totalSpreadAmount = possibleDirectionCount * (room[dustR][dustC]/5);
dustMap[dustR][dustC] += room[dustR][dustC] - totalSpreadAmount;
}
private static void blowWind() {
//위 공기 순환
int upperAirCleanerRow = findUpperAirCleanerRow(room);
int[] dr_upper = {0,-1,0,1};
int[] dc_upper = {1,0,-1,0};
blow(upperAirCleanerRow, dr_upper, dc_upper);
//아래공기 순환
int lowerAirCleanerRow = upperAirCleanerRow+1;
int[] dr_lower = {0,1,0,-1};
int[] dc_lower = {1,0,-1,0};
blow(lowerAirCleanerRow, dr_lower, dc_lower);
}
private static int findUpperAirCleanerRow(int[][] room){
for (int i = 0; i < R; i++) {
if(room[i][0] == -1) return i;
}
throw new RuntimeException("공기청정기 어디감?");
}
private static void blow(int cleanerRow, int[] dr, int[] dc) {
Deque<Integer> path = getBlowPathElements(cleanerRow, dr, dc);
path.addFirst(0); path.pollLast();
updateBlowPath(cleanerRow, dr, dc, path);
}
private static Deque<Integer> getBlowPathElements(int cleanerRow, int[] dr, int[] dc){
Deque<Integer> path = new ArrayDeque<>();
travelBlowPath(cleanerRow, dr, dc, (nextR, nextC) -> path.add(room[nextR][nextC]));
return path;
}
private static void updateBlowPath(int cleanerRow, int[] dr, int[] dc, Deque<Integer> path) {
travelBlowPath(cleanerRow, dr, dc, (nextR, nextC) -> room[nextR][nextC] = path.pollFirst());
}
private static void travelBlowPath(int cleanerRow, int[] dr, int[] dc, Consumer2<Integer,Integer> consumer) {
int directionIdx = 0;
int r = cleanerRow; int c = 0;
while(true) {
directionIdx %= 4;
int nextR = r + dr[directionIdx];
int nextC = c + dc[directionIdx];
if(isValid(nextR, nextC)) {
if(room[nextR][nextC] == -1) break;
consumer.accept(nextR, nextC);
r = nextR; c = nextC;
continue;
}
directionIdx++;
}
}
private static int getDustAmount(int[][] room) {
int total = 0;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if(room[i][j] != -1) total += room[i][j];
}
}
return total;
}
private static boolean isValid(int r, int c) {
if(r < 0 || r >= R) return false;
if(c < 0 || c >= C) return false;
return true;
}
}
@FunctionalInterface
public interface Consumer2<T1, T2> {
void accept(T1 t1, T2 t2);
}
'알고리즘 > PS' 카테고리의 다른 글
[백준 1655번][Java] 가운데를 말해요 (0) | 2021.05.08 |
---|---|
[백준 3055번][Java] 탈출 - BFS (0) | 2021.04.22 |
[백준 15685번][Java] 드래곤 커브 (0) | 2021.04.21 |
[백준 1662번][Java] 압축 (0) | 2021.04.20 |
[14719번][Java] 빗물 (0) | 2021.04.20 |
Comments