본문 바로가기

알고리즘/시뮬

백준_미세먼지안녕!_17144

문제 링크

조건

  • R, C : 방 R x C, 6~50 이하 자연수
  • 현재 칸에서 4방으로 먼지가 퍼질 때, (A / 5)만큼 퍼지고 소수점 이하는 무시함

 

접근 방법

  • 확산은 미세먼지가 있는 모든 칸에서 동시에 발생
    • plus 배열에 모든 칸에서 퍼지는 양 누적 후 한 번에 map에 더해줌
  • 공기청정기 작동 => 위쪽은 반시계, 아래쪽은 시계방향 순환
    • rotate 배열에 위쪽, 아래쪽 확산 방향 저장 후 순서에 맞게 확산시켜줌

 

솔루션

public class Main {

	static int R, C, T;//map R*C, 시간 T초
	static int[][] map, plus;
	static int[] dr = {0,-1,0,1};
	static int[] dc = {1,0,-1,0};
	static int[][] rotate = {//순환 방향 저장
			{0,1,2,3}, {0,3,2,1}	
	};
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(br.readLine().trim());
		R = Integer.parseInt(st.nextToken());
		C = Integer.parseInt(st.nextToken());
		T = Integer.parseInt(st.nextToken());
	
		map = new int[R][C];
		plus = new int[R][C];
		
		int clean = 0;//공기청정기 있는 위치
		for(int i = 0; i < R; i++) {
			st = new StringTokenizer(br.readLine().trim(), " ");
			for(int j = 0; j < C; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
				if(map[i][j] == -1) clean = i;
			}
		}
		
		clean--;
		
		while(T-- > 0) {
			//미세먼지 퍼짐
			int nr, nc;
			for(int i = 0; i < R; i++) {
				for(int j = 0; j < C; j++) {
					if(map[i][j] <= 0) continue;
					int amount = map[i][j] / 5;
					int cnt = 0;
					
					for(int k = 0; k < 4; k++) {
						nr = i+dr[k];
						nc = j+dc[k];
						
						if(nr < 0 || nr >= R || nc < 0 || nc >= C || map[nr][nc] == -1) continue;
						cnt++;
						plus[nr][nc] += amount;
					}
					map[i][j] -= amount * cnt;
				}
			}
			
			
			for(int i = 0; i < R; i++) {
				for(int j = 0; j < C; j++) {
					map[i][j] += plus[i][j];
					plus[i][j] = 0;
				}
			}
			
            
			//공기청정기 바람 순환
			int r = clean;
			int c = 0;
			int d = 0;
			int pre = 0;
			int cur;
			
            		//위쪽 공기 반시계 순환
			while(d < 4) {
				int ro = rotate[0][d];
				while(true) {
					r += dr[ro];
					c += dc[ro];

					if(r < 0 || r >= R || c < 0 || c >= C) break;
					cur = map[r][c];
					if(cur == -1) break;//공기청정기 만남
					map[r][c] = pre;
					pre = cur;
					
				}
				r -= dr[ro];
				c -= dc[ro];
				d++;//방향 바꿈
			}
			
			
			r = clean+1;
			c = 0;
			d = 0;
			pre = 0;
            		//아래쪽 공기 반시계 순환
			while(d < 4) {
				int ro = rotate[1][d];
				while(true) {
					r += dr[ro];
					c += dc[ro];

					if(r < 0 || r >= R || c < 0 || c >= C) break;
					cur = map[r][c];
					if(cur == -1) break;//공기청정기 만남
					map[r][c] = pre;
					pre = cur;
					
				}
				r -= dr[ro];
				c -= dc[ro];
				d++;//방향 바꿈
			}
			
			
		}
		
		int total = 0;
		for(int i = 0; i < R; i++) {
			for(int j = 0; j < C; j++) {
				if(map[i][j] == -1) continue;
				total += map[i][j];
			}
		}
		
		System.out.println(total);
	}

}

 

리뷰

  • 시뮬은 조건 빼먹지 않고 시키는대로 로직 구현해주면 됨..!

'알고리즘 > 시뮬' 카테고리의 다른 글

백준_15685_드래곤 커브  (0) 2021.03.18
백준_20055_컨베이어 벨트 위의 로봇  (0) 2021.03.18
백준_PuyoPuyo_11559  (0) 2021.01.20
백준_빗물_14719  (0) 2021.01.13