문제 풀이 및 개발 공간

[백준] 11967번 불켜기 (gold 2 본문

백준공부/java

[백준] 11967번 불켜기 (gold 2

gomduri43 2024. 5. 7. 20:18

import java.io.*;
import java.util.*;

class Point{
    int x;
    int y;
    public Point(int x, int y){
        this.x=x;
        this.y=y;
    }
}
public class Main{
    static int[] numx={-1,1,0,0};
    static int[] numy={0,0,-1,1};
    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());

        //관계 저장공간.
        ArrayList<Integer>[][] relation=new ArrayList[n+1][n+1];
        for(int i=1; i<=n; i++){
            for(int j=1; j<=n; j++){
                relation[i][j]=new ArrayList<>();
            }
        }
        //좌표는 y*1000 + x 로 압축해서 사용.
        for(int i=0; i<m; i++){
            st=new StringTokenizer(br.readLine());
            int x=Integer.valueOf(st.nextToken());
            int y=Integer.valueOf(st.nextToken());
            int a=Integer.valueOf(st.nextToken());
            int b=Integer.valueOf(st.nextToken());

            relation[y][x].add(b*1000+a);
        }

        //실제 불 켜진 곳 표시. 이곳을 기점으로 표시.
        boolean[][] light=new boolean[n+1][n+1];
        //상하좌우 관계간 방문 노드 체크.
        boolean[][] visit=new boolean[n+1][n+1];

        //처음 1,1방 추가
        Queue<Point> que=new LinkedList<>();
        que.offer(new Point(1,1));
        light[1][1]=true;
        visit[1][1]=true;
        //처음 방 불 켜지므로 초기값 1.
        int answer=1;
        while(!que.isEmpty()){
            Point temp=que.poll();
            //해당 좌표서 가능한 모든 불 켜기.
            for(int i=0; i<relation[temp.y][temp.x].size(); i++){
                int xy=relation[temp.y][temp.x].get(i);

                int y=xy/1000;
                int x=xy%1000;
                //방불이 꺼져 있었을 경우 켜지므로. answer++;
                //문제는 켜진 방을 구하는 문제였다.
                //켜진 방들 중, 방문한 방의 개수를 구하느라 오답이 나왔던 문제..
                if(!light[y][x]){
                    answer++;
                }
                //다른 방을 통해 접근 가능한 곳인데 불이 꺼져있어서 못 들어갔던 곳 추가하기.
                if(!light[y][x] && visit[y][x]){
                    que.offer(new Point(x,y));
                }
                light[y][x]=true;
            }

            for(int k=0; k<4; k++){
                int ty=temp.y+numy[k];
                int tx=temp.x+numx[k];

                if(tx<1 || tx>n || ty<1 || ty>n || visit[ty][tx]){
                    continue;
                }
                //불이켜져 있으면서 아직 가지 않은 곳 추가.
                if(light[ty][tx] && !visit[ty][tx]){
                    visit[ty][tx]=true;
                    que.offer(new Point(tx, ty));
                }
                visit[ty][tx]=true;
            }

        }

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

    }
}