https://www.acmicpc.net/problem/17144
17144번: 미세먼지 안녕!
미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사
www.acmicpc.net
package Main; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Main { //R C T ( 6 <= R,C <= 50, 1 <= T <= 1000) public static int R,C,T; public static int[][] map; public static int[][] tempmap; public static int[] dx = {-1,0,1,0}; public static int[] dy = {0,1,0,-1}; //공기청정기 설치된 A(r,c) : -1 , 나머지값은 미세먼지의 양 //-1 은 2번 위아래로 붙여져있고 가장 윗행, 아랫행과 두칸이상 떨어져있음. public static void main(String[] args) { Scanner sc = new Scanner(System.in); R=sc.nextInt(); C=sc.nextInt(); T=sc.nextInt(); map = new int[R][C]; tempmap = new int[R][C]; for(int i=0;i<R;i++) { for(int j=0;j<C;j++) { map[i][j] = sc.nextInt(); } } for(int i=0;i<T;i++) { virus(); aircleaner(); } int result = 0; for(int i=0;i<R;i++) { for(int j=0;j<C;j++) { if(tempmap[i][j] == -1 || tempmap[i][j] == 0) { continue; }else { result += tempmap[i][j]; } } } System.out.println(result); } // 7 8 5 // 0 0 0 0 0 0 0 9 // 0 0 0 0 3 0 0 8 // -1 0 5 0 0 0 22 0 // -1 8 0 0 0 0 0 0 // 0 0 0 0 0 10 43 0 // 0 0 5 0 15 0 0 0 // 0 0 40 0 0 0 20 0 //map의 값들을 토대로 temp에서 각 temp[r][c] 를 모두 돌면서 r, c가 >=0 크고 <=0 이며 진공청소기가 있는 위치가 아니라면 //temp에 더합니다. 이유는 map에서 하면 값이 변하면서 '동시에 미세먼지가 확산'하는것이 불가능합니다. public static void virus() { //Arc : map(r,c) //diffusedArc : Arc - (Arc/5)*diffusedcount for(int i=0;i<R;i++) { for(int j=0;j<C;j++) { tempmap[i][j] = 0; } } for(int i=0;i<R;i++) { for(int j=0;j<C;j++) { if(map[i][j] == 0){ continue; } if(map[i][j] == -1) { tempmap[i][j] = -1; continue; } int originalArc = map[i][j]; int Arc = originalArc; int diffusedcount=0; for(int k=0;k<4;k++) { int nrow = i + dx[k]; int ncol = j + dy[k]; if(nrow >= 0 && nrow < R && ncol >=0 && ncol < C && map[nrow][ncol] != -1) { diffusedcount += 1; tempmap[nrow][ncol] += Arc / 5; } } tempmap[i][j] += Arc - (Arc / 5) * diffusedcount; } } } public static void aircleaner() { int aircleaner_TopX =0 ; int aircleaner_TopY =0 ; int aircleaner_BottomX =0; int aircleaner_BottomY =0; //공기청정기의 위치 구하기 boolean flag = false; for(int i=0;i<R;i++) { if(flag) { break; } for(int j=0;j<C;j++) { if(tempmap[i][j] == -1) { aircleaner_TopX = i; aircleaner_TopY = j; aircleaner_BottomX = i+1; aircleaner_BottomY = j; flag = true; break; } } } //공기청정기 상단 부분 코딩(반시계방향) for(int x=aircleaner_TopX-1;x>0;x--) { tempmap[x][0] = tempmap[x-1][0]; } for(int y=0;y<C-1;y++) { tempmap[0][y] =tempmap[0][y+1]; } for(int x=0;x<aircleaner_TopX;x++) { tempmap[x][C-1] = tempmap[x+1][C-1]; } for(int y=C-1;y>0;y--) { tempmap[aircleaner_TopX][y] = tempmap[aircleaner_TopX][y-1]; } tempmap[aircleaner_TopX][aircleaner_TopY+1] = 0; //공기청정기 상단 하단 부분 코딩(시계방향) for(int x=aircleaner_BottomX+1;x<R-1;x++) { tempmap[x][0] = tempmap[x+1][0]; } for(int y=0;y<C-1;y++) { tempmap[R-1][y] =tempmap[R-1][y+1]; } for(int x=R-1;x>aircleaner_BottomX;x--) { tempmap[x][C-1] = tempmap[x-1][C-1]; } for(int y=C-1;y>0;y--) { tempmap[aircleaner_BottomX][y] = tempmap[aircleaner_BottomX][y-1]; } tempmap[aircleaner_BottomX][aircleaner_BottomY+1] = 0; for(int i=0;i<R;i++) { for(int j=0;j<C;j++) { map[i][j] = tempmap[i][j]; } } } }
이문제는 직접 다풀었습니다.
진행하면서 헷갈렸던점은
1.미세먼지 확산과 공기청정기가 T초마다 계속 같이 반복하는 것을 헷갈렸습니다. 처음에 미세먼지 확산 1번하고 공기청정지가 작동하는 줄 알았습니다.
2.공기청징기에 의해 반시계방향, 시계방향으로 미세먼지가 이동하는데, 그 과정을 처음에 직관적인 순서로 바람이 부는대로 진행하려다가 반대로 뒷방향순서로 하면 금방해결할 수 있습니다.
3. 1번과 연결되는 것인데, 계속해서 새로 확산을 진행하게 저는 map, tempmap 2가지 변수를 사용하여 진행했는데 이때 확산된것이 확정되고서 map = tempmap 에 넣고, 그 이후에 tempmap 전체를 0으로 초기화시켜주어야 했습니다. 아니라면 게속해서 tempmap += 이런식으로 누적된 미세먼지가 나와서 미세먼지 양이 엄청나게 나옵니다.
'알고리즘 > 삼성SW' 카테고리의 다른 글
[삼성 SW 역량 테스트 기출 문제] 주사위 굴리기 2 - 레벨1 (0) | 2022.07.05 |
---|---|
[삼성 SW 역량 테스트 기출 문제] 마법사 상어와 비바라기 - 레벨1 (0) | 2022.07.04 |
[삼성 SW 역량 테스트 기출 문제] 마법사 상어와 토네이도 - 레벨1 (0) | 2022.07.02 |
[삼성 SW 역량 테스트 기출 문제] 드래곤 커브 - 레벨1 (0) | 2022.04.05 |
[삼성 SW 역량 테스트 기출 문제] 경사로 - 레벨1 (0) | 2022.03.15 |