๐Ÿ“ ์•Œ๊ณ ๋ฆฌ์ฆ˜/Simulation

[๋ฐฑ์ค€] 2933๋ฒˆ / 18500๋ฒˆ: ๋ฏธ๋„ค๋ž„ 1, 2 (JAVA)

์ ์ด 2022. 3. 25. 01:23
๋ฐ˜์‘ํ˜•

๋ฌธ์ œ (GOLD 2)

https://www.acmicpc.net/problem/18500

 

18500๋ฒˆ: ๋ฏธ๋„ค๋ž„ 2

์ฐฝ์˜๊ณผ ์ƒ๊ทผ์€ ํ•œ ๋™๊ตด์„ ๋†“๊ณ  ์†Œ์œ ๊ถŒ์„ ์ฃผ์žฅํ•˜๊ณ  ์žˆ๋‹ค. ๋‘ ์‚ฌ๋žŒ์€ ๋ง‰๋Œ€๊ธฐ๋ฅผ ์„œ๋กœ์—๊ฒŒ ๋˜์ง€๋Š” ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•ด ๋ˆ„๊ตฌ์˜ ์†Œ์œ ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค. ์‹ธ์›€์€ ๋™๊ตด์—์„œ ๋ฒŒ์–ด์ง„๋‹ค. ๋™๊ตด์—๋Š” ๋ฏธ๋„ค๋ž„

www.acmicpc.net


ํ’€์ด

์‹œ๋ฎฌ๋ ˆ์ด์…˜์€ ๋ฌธ์ œ๋ฅผ ์ฒœ์ฒœํžˆ ๋ณด๋ฉด์„œ ํ•˜๋‚˜ํ•˜๋‚˜ ๊ตฌํ˜„ํ•˜๋Š”๊ฒŒ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ ๊ฐ™๋‹ค.

Logic

  1. ๋†’์ด ์ž…๋ ฅ ๋ฐ›๊ธฐ
  2. ๋˜์ง€๋Š” ์œ„์น˜์— ๋”ฐ๋ผ ๋ถ„๊ธฐ
  3. ์—†์–ด์งˆ ๋ฏธ๋„ค๋ž„ ์œ„์น˜ ์ฐพ๊ธฐ 
  4. ์—†์–ด์งˆ ๋ฏธ๋„ค๋ž„์„ ์ค‘์‹ฌ์œผ๋กœ
    ์˜ค๋ฅธ์ชฝ ๊ณต๊ฒฉ์ด๋ฉด ์ƒ, ํ•˜, ์ขŒ
    ์™ผ์ชฝ ๊ณต๊ฒฉ์ด๋ฉด  ์ƒ, ํ•˜, ์šฐ 
    ํƒ์ƒ‰ํ•˜๋ฉฐ, ๋–จ์–ด์งˆ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ ( breakMineral() )
    1. BFS ๋Œ๋ฉฐ, ๋ฐ”๋‹ฅ๊ณผ ๋งž๋‹ฟ์•„ ์žˆ๋Š” ๊ณณ์ด ์žˆ๋Š”์ง€ ํ™•์ธ
    2. ์žˆ์œผ๋ฉด false ๋ฆฌํ„ด, ์—†์œผ๋ฉด true ๋ฆฌํ„ด
    3. ํƒ์ƒ‰ ์‹œ, broken ๋ฆฌ์ŠคํŠธ์— ํด๋Ÿฌ์Šคํ„ฐ๋“ค์˜ ์œ„์น˜ ์ €์žฅ
  5. ํด๋Ÿฌ์Šคํ„ฐ ๋–จ์–ด๋œจ๋ฆฌ๊ธฐ ( fallMineral() )
    1. ๋–จ์–ด์งˆ ๋ฏธ๋„ค๋ž„์˜ ์ž๋ฆฌ๋ฅผ ์ฒดํฌํ•˜์ง€ ์•Š๋„๋ก ์ž„์‹œ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด ๋–จ์–ด์งˆ ๋ฏธ๋„ค๋ž„ ์ž๋ฆฌ๋ฅผ false ์ฒ˜๋ฆฌ
    2. ๋ชจ๋“  ์›์†Œ๊ฐ€ ์•„๋ž˜๋กœ ํ•œ์นธ ์”ฉ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋Š”์ง€ ํŒ๋ณ„
    3. ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๊ธฐ์กด์˜ ๋ฏธ๋„ค๋ž„ ์ž๋ฆฌ๋ฅผ ๋จผ์ € false๋กœ ๋ชจ๋‘ ๋ฐ”๊ฟ”์คŒ
      -> ๋‚˜์ค‘์— ๊ฒน์น  ์œ„ํ—˜ ์žˆ์Œ ใ… ใ… 
    4. ์ƒˆ๋กœ์šด ๋ฏธ๋„ค๋ž„ ์ž๋ฆฌ๋ฅผ true ์ฒ˜๋ฆฌ
    5. ํ•œ์นธ ์•„๋ž˜๋กœ ๋‚ด๋ ค๊ฐ„ ์ธ๋ฑ์Šค๋กœ ๋‹ค์‹œ ์ €์žฅ
    6. ๋–จ์–ด์งˆ ์ˆ˜ ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต

๋†“์ณค๋˜ ๋ถ€๋ถ„

  • ์•„๋ž˜๋ถ€๋ถ„ ์ฒดํฌ!
    => ์•„๋ž˜๋Š” ๋‹น์—ฐํžˆ ๋‹ฟ์•„์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ ์ฒดํฌ๋ฅผ ์•ˆํ–ˆ์—ˆ์Œ ใ… ใ… 
  • ๋–จ์–ด๋œจ๋ฆฌ๊ธฐ ์ „, ๋ฏธ๋„ค๋ž„ ์ž๋ฆฌ ๋จผ์ € ๋ชจ๋‘ false์ฒ˜๋ฆฌ
    => ํ•˜๋‚˜์”ฉ ๋Œ๋ฉฐ false ๋ฐ”๊พธ๊ณ  true๋กœ ๋ฐ”๋กœ ๋ฐ”๊พธ๋Š” ๋กœ์ง์„ ํ–ˆ์—ˆ์ง€๋งŒ, ์ž๋ฆฌ๊ฐ€ ๊ฒน์น  ๊ฒฝ์šฐ์— ๋–จ์–ด์ง„ ๋ฏธ๋„ค๋ž„ ์ž๋ฆฌ๋„ false์ฒ˜๋ฆฌ ๋จ

์ฝ”๋“œ

๋”๋ณด๊ธฐ
package simulation;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main_2933_๋ฏธ๋„ค๋ž„ {
    static int[] di = {-1, 0, 1, 0};
    static int[] dj = {0, 1, 0, -1};
    static int R, C;
    static boolean[][] mineral;
    static int N;
    static List<int[]> broken;

    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());
        mineral = new boolean[R][C];
        for (int i = 0; i < R; i++) {
            String str = br.readLine();
            for (int j = 0; j < C; j++) {
                mineral[i][j] = (str.charAt(j) == '.') ? false : true;
            }
        }

        N = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            int height = R-Integer.parseInt(st.nextToken());
            broken = new ArrayList<>();
            if(i%2==0){     // ์™ผ์ชฝ์—์„œ ๊ณต๊ฒฉ
                int pos = 0;
                while(pos<C && !mineral[height][pos++]);            // ๋ถ€์‹ค ๋ฏธ๋„ค๋ž„์˜ j๊ฐ’ ์ฐพ๊ธฐ
                if(pos >= C && !mineral[height][pos-1]) continue;
                mineral[height][--pos] = false;     // ๋ถ€์‹ค ๋ฏธ๋„ค๋ž„ false ์ฒ˜๋ฆฌ
                if(pos < C-1 && height < R-1 && mineral[height][pos+1] && breakMineral(height, pos+1, height+1)) fallMineral();     // ์˜ค๋ฅธ์ชฝ ํƒ์ƒ‰
                else if(pos < C && height > 0 && mineral[height-1][pos] &&breakMineral(height-1, pos, height)) fallMineral();   // ์œ„์ชฝ ํƒ์ƒ‰
                else if(pos < C && height < R-1 && mineral[height+1][pos] &&breakMineral(height+1, pos, height)) fallMineral(); // ์•„๋ž˜์ชฝ ํƒ์ƒ‰
            }
            else if(i%2 == 1){  // ์˜ค๋ฅธ์ชฝ์—์„œ ๊ณต๊ฒฉ
                int pos = C-1;
                while(pos>=0 && !mineral[height][pos--]);   // ๋ถ€์‹ค ๋ฏธ๋„ค๋ž„ j๊ฐ’ ์ฐพ๊ธฐ
                if(pos < 0 && !mineral[height][pos+1]) continue;
                mineral[height][++pos] = false;
                if(pos > 0 && height < R-1 && mineral[height][pos-1] && breakMineral(height, pos-1, height+1)) fallMineral();   // ์™ผ์ชฝ ํƒ์ƒ‰
                else if(pos >= 0 && height > 0 && mineral[height-1][pos] && breakMineral(height-1, pos, height)) fallMineral(); // ์œ„์ชฝ ํƒ์ƒ‰
                else if(pos >= 0 && height < R-1 && mineral[height+1][pos] && breakMineral(height+1, pos, height)) fallMineral();   // ์•„๋ž˜์ชฝ ํƒ์ƒ‰
            }
        }

        for(int i =0 ; i < R ; i++){
            for(int j = 0 ; j < C ; j++){
                System.out.print((mineral[i][j])?'x':'.');
            }
            System.out.println();
        }
    }

    private static void fallMineral() {
        out:while(true) {
            boolean[][] tmpMin = new boolean[R][C];
            for(int i =0 ; i < R ; i++) tmpMin[i] = Arrays.copyOf(mineral[i], C);   // ๋–จ์–ด์งˆ ๋ฏธ๋„ค๋ž„์„ ์ฒดํฌํ•˜์ง€ ์•Š๋„๋ก ์ž„์‹œ ๋ฐฐ์—ด ๋งŒ๋“ค์–ด ์คŒ
            for(int[] c : broken) tmpMin[c[0]][c[1]] = false;   // ๋–จ์–ด์งˆ ๋ฏธ๋„ค๋ž„ ์ž๋ฆฌ๋ฅผ false
            for(int[] c : broken) {
                if (c[0]+1 >= R || tmpMin[c[0]+1][c[1]]) {  // ๋ชจ๋“  ์›์†Œ๊ฐ€ ์•„๋ž˜๋กœ ํ•œ์นธ์”ฉ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋Š”์ง€ ํŒ๋ณ„
                    break out;
                }
            }
            // ํ•œ์นธ์”ฉ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค!
            for(int[] c : broken) mineral[c[0]][c[1]] = false;  // ๊ธฐ์กด์˜ ๋ฏธ๋„ค๋ž„ ์ž๋ฆฌ๋ฅผ ๋จผ์ € false ์ฒ˜๋ฆฌ -> ๋‚˜์ค‘์— ๊ฒน์น  ์œ„ํ—˜ ์žˆ์Œ
            for(int i =0 ; i < broken.size() ; i++){
                int[] tmp = broken.get(i);
                mineral[tmp[0]+1][tmp[1]] = true;   // ์ƒˆ๋กœ์šด ์ž๋ฆฌ true
                broken.set(i, new int[]{tmp[0]+1, tmp[1]}); // ํ•œ์นธ ์•„๋ž˜๋กœ ๋‚ด๋ ค๊ฐ„ ์ธ๋ฑ์Šค๋กœ ๋‹ค์‹œ ์ €์žฅ
            }
        }
    }

    private static boolean breakMineral(int i, int j, int height) {
        boolean[][] visited = new boolean[R][C];
        Queue<int[]> q = new ArrayDeque<>();
        q.offer(new int[]{i, j});
        broken.add(new int[]{i, j});
        visited[i][j] = true;
        while(!q.isEmpty()){
            int[] cur = q.poll();
            for(int d= 0 ; d < 4 ; d++){
                int ni = cur[0]+di[d];
                int nj = cur[1]+dj[d];
                if(0<=ni&&ni<R && 0<=nj&&nj<C && mineral[ni][nj] && !visited[ni][nj]){
                    if(ni == R-1){      // ๋ฐ”๋‹ฅ๊ณผ ๋งž๋‹ฟ์•„ ์žˆ๋Š” ๊ณณ์ด ์žˆ์œผ๋ฉด ์•ˆ ๋–จ์–ด์ง€๋Š” ๊ฑฐ์ž„
                        broken.clear();
                        return false;
                    }
                    q.offer(new int[]{ni, nj});
                    visited[ni][nj] = true;
                    broken.add(new int[]{ni, nj});
                }
            }
        }
        return true;
    }
}
๋ฐ˜์‘ํ˜•