|
| 1 | +package study.week09; |
| 2 | + |
| 3 | +import java.io.BufferedReader; |
| 4 | +import java.io.IOException; |
| 5 | +import java.io.InputStreamReader; |
| 6 | +import java.util.LinkedList; |
| 7 | +import java.util.Queue; |
| 8 | + |
| 9 | +// 커넥티드 카 실험 |
| 10 | +// bfs, 투포인터 |
| 11 | + |
| 12 | +/** |
| 13 | + * 답지를 확인하였다. |
| 14 | + * 시작 커넥트 카 부터 왼쪽, 오른쪽으로 갈 수 있는 최저, 최대 값을 구한다. |
| 15 | + * 그래서 해당 범위의 locate에 해당하는 커넥트 카들은 방문 처리를 하고, 다음 탐색 지점으로 이용하기 위해 Queue 에 넣는다. |
| 16 | + * 또한 minLeftLocation, maxRightLocation 의 값을 게속 최저, 최대만 남기게 하는데, 그 이유는 새로운 커넥트 카에서 탐색을 한다 하여도, |
| 17 | + * 모든 경우의 수를 따지는 문제이기 때문에 가장 작고, 큰 locate, idx 범위는 이미 처리가 되었다는 뜻이기 때문이다. |
| 18 | + * 그래서 계속 업데이트 되는 최대 범위에 있어서 포함이 되면 visited에 표시하고, 포함이 되지 않으면 넘어간다. |
| 19 | + * 최종적으로 visited 배열에는 연결이 가능한 connected car 만 체크가 된다. |
| 20 | + */ |
| 21 | +public class BOJ_25395 { |
| 22 | + |
| 23 | + private static int now; |
| 24 | + |
| 25 | + static class Connector { |
| 26 | + |
| 27 | + int locate; |
| 28 | + int fuel; |
| 29 | + |
| 30 | + public Connector(int locate, int fuel) { |
| 31 | + this.locate = locate; |
| 32 | + this.fuel = fuel; |
| 33 | + } |
| 34 | + } |
| 35 | + |
| 36 | + static boolean[] visited; |
| 37 | + static int N; |
| 38 | + static int S; |
| 39 | + static Connector[] connectors; |
| 40 | + |
| 41 | + public static void main(String[] args) throws IOException { |
| 42 | + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); |
| 43 | + StringBuilder sb = new StringBuilder(); |
| 44 | + |
| 45 | + String[] s = br.readLine().split(" "); |
| 46 | + N = Integer.parseInt(s[0]); |
| 47 | + S = Integer.parseInt(s[1]); |
| 48 | + visited = new boolean[N + 1]; |
| 49 | + connectors = new Connector[N+1]; |
| 50 | + |
| 51 | + String [] strLocates = br.readLine().split(" "); |
| 52 | + String [] strFuels = br.readLine().split(" "); |
| 53 | + |
| 54 | + for(int i=0; i<N; i++){ |
| 55 | + int locate = Integer.parseInt(strLocates[i]); |
| 56 | + int fuel = Integer.parseInt(strFuels[i]); |
| 57 | + connectors[i+1] = new Connector(locate, fuel); |
| 58 | + } |
| 59 | + |
| 60 | + findConnects(); |
| 61 | + |
| 62 | + for(int i=1; i<=N; i++){ |
| 63 | + if(visited[i])sb.append(i).append(" "); |
| 64 | + } |
| 65 | + |
| 66 | + System.out.println(sb); |
| 67 | + } |
| 68 | + |
| 69 | + private static void findConnects() { |
| 70 | + Queue<Integer> q = new LinkedList<>(); |
| 71 | + int minLeftLocate = connectors[S].locate; |
| 72 | + int maxRightLocate = connectors[S].locate; |
| 73 | + int minLeftIdx = S; |
| 74 | + int maxRightIdx = S; |
| 75 | + visited[S] = true; |
| 76 | + q.add(S); |
| 77 | + while (!q.isEmpty()){ |
| 78 | + now = q.poll(); |
| 79 | + minLeftLocate = Math.min(minLeftLocate, connectors[now].locate - connectors[now].fuel); |
| 80 | + maxRightLocate = Math.max(maxRightLocate, connectors[now].locate + connectors[now].fuel); |
| 81 | + |
| 82 | + for(int left = minLeftIdx-1; left > 0; left--){ |
| 83 | + if(connectors[left].locate < minLeftLocate) break; |
| 84 | + if(visited[left]) continue; |
| 85 | + |
| 86 | + minLeftIdx = Math.min(minLeftIdx, left); |
| 87 | + visited[left] = true; |
| 88 | + q.add(left); |
| 89 | + } |
| 90 | + |
| 91 | + for(int right = maxRightIdx+1; right <= N; right++){ |
| 92 | + if(connectors[right].locate > maxRightLocate)break; |
| 93 | + if(visited[right]) continue; |
| 94 | + |
| 95 | + maxRightIdx = Math.max(maxRightIdx, right); |
| 96 | + visited[right] = true; |
| 97 | + q.add(right); |
| 98 | + } |
| 99 | + } |
| 100 | + } |
| 101 | +} |
0 commit comments