문제 풀이 및 개발 공간

[백준] 14502번 연구소 (gold 4 본문

백준공부/java

[백준] 14502번 연구소 (gold 4

gomduri43 2023. 12. 29. 15:31

import java.io.*;
import java.util.*;
class Point{
    int x;
    int y;
    public Point(int x, int y){
        this.x=x;
        this.y=y;
    }
}

class Wall{
    int f;
    int s;
    int t;
    public Wall(int f, int s, int t){
        this.f=f;
        this.s=s;
        this.t=t;
    }
}

public class Main{
    static int[] numx={-1,1,0,0};
    static int[] numy={0,0,-1,1};
    static int[] num;
    static int[] temp=new int[3];
    static ArrayList<Wall> cases=new ArrayList<>();
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st=new StringTokenizer(br.readLine());
        int n=Integer.valueOf(st.nextToken());
        int m=Integer.valueOf(st.nextToken());

        int[][] map=new int[n+1][m+1];
        num=new int[n*m+1];
        HashMap<Integer,Integer> dict=new HashMap<>();
        for(int i=1; i<=n; i++){
            st=new StringTokenizer(br.readLine());
            for(int j=1; j<=m; j++){
                map[i][j]=Integer.valueOf(st.nextToken());
                if(map[i][j]==2){
                    dict.put(j*10+i,1);
                }
                else if(map[i][j]==0){
                    num[(i-1)*m+j]=i*10+j;
                }
            }
        }

        ArrayList<Integer> virus=new ArrayList<>(dict.keySet());
        dfs(0,0);
        Queue<Point> que=new LinkedList<>();
        int max=Integer.MIN_VALUE;

        for(int i=0; i<cases.size(); i++){
            Wall temp=cases.get(i);
            int[][] newMap=new int[n+1][m+1];
            for(int y=1; y<=n; y++){
                for(int x=1; x<=m; x++){
                    newMap[y][x]=map[y][x];
                }
            }
            newMap[temp.f/10][temp.f%10]=1;
            newMap[temp.s/10][temp.s%10]=1;
            newMap[temp.t/10][temp.t%10]=1;

            for(int k=0; k<virus.size(); k++){
                que.offer(new Point(virus.get(k)/10 , virus.get(k)%10 ));
            }

            while(!que.isEmpty()){
                Point p=que.poll();
                for(int k=0; k<4; k++){
                    int tempx=p.x+numx[k];
                    int tempy=p.y+numy[k];

                    if(tempx<1 || tempx>m || tempy<1 || tempy>n || newMap[tempy][tempx]==1 || newMap[tempy][tempx]==2){
                        continue;
                    }
                    newMap[tempy][tempx]=2;
                    que.offer(new Point(tempx,tempy));

                }

            }
            int depth=0;
            for(int y=1; y<=n; y++){
                for(int x=1; x<=m; x++){
                    if(newMap[y][x]==0){
                        depth++;
                    }
                }
            }

            max=Math.max(depth, max);
        }

        bw.write(max+"");
        bw.flush();


    }
    public static void dfs(int d, int n){
        if(n==3){
            cases.add(new Wall(temp[0], temp[1], temp[2]));
            return;
        }
        else{
            for(int i=d+1; i<num.length; i++){
                if(num[i]!=0) {
                    temp[n] = num[i];
                    dfs(i, n + 1);
                }
            }
        }

    }
}

//빈칸에서 세울 수 있는 벽의 경우를 백트래킹으로 구한뒤, 벽을 세울수 있는 케이스를 돌면서 
//벽을 세우고, 바이러스 전파를 함, 완료 후에 안전한 영역을 구하여 가장 넓은 영역인 경우의 
//크기를 구했다.