Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- SWEA
- database
- 코딩테스트실력진단
- 다익스트라
- 그래프
- SSAFY
- 유니온파인드
- Java
- 트러블슈팅
- BFS
- 알고리즘
- 기본유형
- 다시보기
- Spring
- Union Find
- 그리디
- 백준
- 자바
- 부분수열의합2
- DP
- 코드트리
- 코테
- 싸피
- JUnit
- JPA
- 완전탐색
- 완탐
- 코딩테스트
- 알고리즘기본개념
- DFS
Archives
- Today
- Total
HwangHub
[Java/BFS] 소프티어. 안전운전을 도와줄 차세대 지능형 교통시스템 본문
🤔 Intuition
그래프 탐색 기법을 이용한 완탐으로 보였다.
다만, 움직이는 과정에서 현재 자율주행 차량의 진행방향을 기억해두고, 진행 가능 여부를 판단할 때 이용해야 한다는 점만 고려하면 된다. 진행 방향을 고려하기 위해 mod 4를 한 값이 0 ,1 , 2 , 3 단위로 움직일 수 있도록 -1 해서 각 방향들을 받아주었다.
그리고 방문 여부는 점수 중복 계산을 방지하기 위해서만 사용하였다.
단순한 문제인데, 괜히 문제가 길어서 피곤하게 만듦으로써 사람을 쫄게 하는 문제이다.
🔎 Algorithm & Complexity
* @algorithm BFS
* @time O(N^2) : 그래프 완탐
* @memory O(N^2) : 배열 저장
👨🏻💻 Logic
1. 기본 정보를 저장해둔다.
2. BFS 탐색을 진행한다. (주석 참고)
import java.io.*;
import java.util.*;
public class Main {
private static int N, T, ans;
private static int[][][] arr;
private static List<int[]>[] delta;
private static boolean[][] visited;
private static final int DOWN = 3;
private static final int RIGHT = 0;
private static final int UP = 1;
private static final int LEFT = 2;
public static void main(String[] args) throws IOException {
// 기본 선언
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringBuilder sb = new StringBuilder();
StringTokenizer st;
// 기본 정보 저장
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
T = Integer.parseInt(st.nextToken());
arr = new int[N][N][4];
delta = new ArrayList[12];
visited = new boolean[N][N];
for (int i = 0; i < 12; i++) {
delta[i] = new ArrayList<>();
}
// 움직임 정보 저장
delta[0].add(new int[]{-1, 0});
delta[0].add(new int[]{0, 1});
delta[0].add(new int[]{1, 0});
delta[1].add(new int[]{0, -1});
delta[1].add(new int[]{-1, 0});
delta[1].add(new int[]{0, 1});
delta[2].add(new int[]{-1, 0});
delta[2].add(new int[]{0, -1});
delta[2].add(new int[]{1, 0});
delta[3].add(new int[]{0, -1});
delta[3].add(new int[]{1, 0});
delta[3].add(new int[]{0, 1});
delta[4].add(new int[]{-1, 0});
delta[4].add(new int[]{0, 1});
delta[8].add(new int[]{0, 1});
delta[8].add(new int[]{1, 0});
delta[5].add(new int[]{0, -1});
delta[5].add(new int[]{-1, 0});
delta[9].add(new int[]{-1, 0});
delta[9].add(new int[]{0, 1});
delta[6].add(new int[]{1, 0});
delta[6].add(new int[]{0, -1});
delta[10].add(new int[]{0, -1});
delta[10].add(new int[]{-1, 0});
delta[7].add(new int[]{0, 1});
delta[7].add(new int[]{1, 0});
delta[11].add(new int[]{1, 0});
delta[11].add(new int[]{0, -1});
// 각 교차로에 주어진 신호등 정보 저장
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
st = new StringTokenizer(br.readLine());
arr[i][j][0] = Integer.parseInt(st.nextToken()) - 1;
arr[i][j][1] = Integer.parseInt(st.nextToken()) - 1;
arr[i][j][2] = Integer.parseInt(st.nextToken()) - 1;
arr[i][j][3] = Integer.parseInt(st.nextToken()) - 1;
}
}
// 답안 구하기
bfs();
br.close();
bw.write(String.valueOf(ans));
bw.flush();
bw.close();
}
private static void bfs() {
Queue<int[]> q = new ArrayDeque<>();
q.add(new int[]{0, 0, UP}); // 최초 위치는 (0,0)으로, 방향은 UP으로 설정하고 진행
visited[0][0] = true;
ans = 1; // 이미 한 칸은 방문한 채로 시작
int[][] time = new int[N][N]; // 시간을 계산하기 위한 배열 선언
time[0][0] = 0;
while (!q.isEmpty()) {
int[] now = q.poll();
int y = now[0];
int x = now[1];
if (time[y][x] == T) { // 목표 시간이 다 되면 종료
return;
}
int nowDir = now[2];
int light = arr[y][x][time[y][x] % 4]; // 신호등 idx 추출
for (int[] d : delta[light]) { // 신호등에 따라 갈 수 있는 좌표 전부 탐색
int ny = y + d[0];
int nx = x + d[1];
if (canGo(ny, nx, nowDir, light)) { // 맵을 이탈하지 않으면서, 진행 방향이 신호등과 일치하면 can go
if (!visited[ny][nx]) { // 처음 방문하는 교차로 수 체크
ans++;
visited[ny][nx] = true;
}
time[ny][nx] = time[y][x] + 1;
q.add(new int[]{ny, nx, getDir(d[0], d[1], light % 4)});
}
}
}
}
private static int getDir(int dy, int dx, int dir) { // 진행방향 변환 메서드
if (dir == DOWN) { // 아래로 이동하면서
if (dx < 0) {
return LEFT;
} else if (dx == 0) {
return DOWN;
} else if (dx > 0) {
return RIGHT;
}
} else if (dir == RIGHT) {
if (dy < 0) {
return UP;
} else if (dy == 0) {
return RIGHT;
} else if (dy > 0) {
return DOWN;
}
} else if (dir == UP) {
if (dx < 0) {
return LEFT;
} else if (dx == 0) {
return UP;
} else if (dx > 0) {
return RIGHT;
}
} else if (dir == LEFT) {
if (dy < 0) {
return UP;
} else if (dy == 0) {
return LEFT;
} else if (dy > 0) {
return DOWN;
}
}
return -1;
}
private static boolean canGo(int y, int x, int nowDir, int lightDir) {
return inRange(y, x) && (nowDir == lightDir % 4);
}
private static boolean inRange(int y, int x) {
return y >= 0 && y < N && x >= 0 && x < N;
}
}
'workspace > 알고리즘' 카테고리의 다른 글
[Java/다익스트라] 백준 13549. 숨바꼭질3 (0) | 2024.03.21 |
---|---|
[Java/Map] 코드트리. 두 수의 합 (0) | 2024.03.20 |
[Java/BFS] 소프티어. 나무섭지 (0) | 2024.03.14 |
[Java/Simulation] 백준 16236. 아기상어 (0) | 2024.03.13 |
[Java/BruteForce] 소프티어. 함께하는효도 (0) | 2024.03.13 |
Comments