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 += 이런식으로 누적된 미세먼지가 나와서 미세먼지 양이 엄청나게 나옵니다.

 

 

+ Recent posts