티스토리 뷰
출저 : https://www.acmicpc.net/problem/11967
"상태 공간에 대한 정확한 이해가 필요"
먼저 상태 공간에 대한 정의가 중요하다. 나는 방문 여부를 체크하는 visited와 해당 방에 불이 켜져있는지를 체크하는 light 두 개의 2차원 배열을 두었다. 그리고 방에 있는 스위치 정보는 x,y 좌표를 x*N +y 를 사용해 index로 변환해서 저장했다. 따라서 아래와 같은 변수를 사용한다.
ArrayList<Integer>[] list;
A 방에 도착해서 B 방에 불을 켰고 B까지 갈 수 있다면 가정했을 때, 그 방을 기점으로 해서 다시 탐색을 시작해야함을 주의한다. 나는 처음에 불을 다시 켰을 때 visited 배열을 초기화 시켰는데, 통과는 했으나 시간이 오래 걸려 그냥 q에 넣어주는식으로 구현함.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; import java.util.StringTokenizer; public class Main { static int N,M; static ArrayList<Integer>[] list; static boolean[][] visited; static boolean[][] light; static int[] dx = {0,0,1,-1}; static int[] dy = {1,-1,0,0}; static Queue<Integer> q = new LinkedList<>(); static int cnt; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); M = Integer.parseInt(st.nextToken()); visited = new boolean[N][N]; light = new boolean[N][N]; list = new ArrayList [N*N]; for (int i = 0; i < N*N; i++) { list[i] = new ArrayList<Integer>(); } for (int i = 0; i < M; i++) { st = new StringTokenizer(br.readLine()); int x = Integer.parseInt(st.nextToken()) - 1; int y = Integer.parseInt(st.nextToken()) - 1; int a = Integer.parseInt(st.nextToken()) - 1; int b = Integer.parseInt(st.nextToken()) - 1; list[x*N+y].add(a*N+b); } visited[0][0] = light[0][0] = true; q.add(0); while(!q.isEmpty()) { int cur = q.poll(); int x = cur / N; int y = cur % N; turnOn(cur); for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if(!isRange(nx, ny) || visited[nx][ny] || !light[nx][ny]) continue; int next = nx*N + ny; visited[nx][ny] = true; q.add(next); } } System.out.println(cnt+1); } static void turnOn(int idx) { for (int i = 0; i < list[idx].size(); i++) { int num = list[idx].get(i); int x = num / N; int y = num % N; if(light[x][y]) continue; light[x][y] = true; cnt++; // 만약 불이 켜진 방에 갈 수 있다면, 검색한다. for (int j = 0; j < 4; j++) { int nx = x + dx[j]; int ny = y + dy[j]; if(isRange(nx, ny) && visited[nx][ny]) { q.add(nx*N + ny); break; } } } } static boolean isRange(int x,int y) { if(x < 0 || x >= N || y < 0 || y >= N) return false; return true; } } | cs |
'Study > 알고리즘 문제풀이' 카테고리의 다른 글
백준 1799. 비숍 :: 돼지개발자 (2) | 2018.12.06 |
---|---|
백준 14620. 꽃길 :: 돼지개발자 (0) | 2018.12.06 |
백준 15663. N과 M (9) :: 돼지개발자 (0) | 2018.12.05 |
백준 14226. 이모티콘 :: 돼지개발자 (0) | 2018.12.05 |
백준 2839. 설탕 배달 :: 돼지개발자 (0) | 2018.12.05 |
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday