문제 요약
집에서 페스티벌까지 맥주를 마시며 가려고 한다.
맥주는 한 번에 1000미터를 이동할 수 있을만큼만 들고다닌다.
편의점에서 맥주를 충전할 수 있다.
집에서 페스티벌까지 맥주가 떨어지지 않고 갈 수 있을지 없을지 구하라.
입력
첫째줄에 테스트 케이스의 개수 t가 주어진다. (t <= 50)
각 테스트 케이스의 첫 줄에는 편의점의 개수 n이 주어진다. (0 <= n <= 100)
다음 n+2 줄에는 각각 집, 편의점(n개), 페스티벌의 좌표가 주어진다. 각 좌표는 두 정수 x와 y로 이루어져 있다. (-32768 <= x, y <= 32767)
도시는 직사각형 모양으로 생겼고 두 좌표 사이의 거리는 x 좌표의 차이 + y 좌표의 차이다. (맨해튼 거리)
출력
각 테스트 케이스에 대해서 맥주가 떨어지지 않으면 "happy", 맥주가 중간에 떨어지면 "sad"를 출력한다.
예제 입력
2
2
0 0
1000 0
1000 1000
2000 1000
2
0 0
1000 0
2000 1000
2000 2000
예제 출력
happy
sad
// https://www.acmicpc.net/problem/9205
// 20.8.13. ventania1680
package BOJ;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Stack;
import java.util.StringTokenizer;
public class BOJ9205 {
public static void solution() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();
Stack<int[]> s = new Stack<>();
while(t-- > 0) {
int n = Integer.parseInt(br.readLine());
StringTokenizer st;
int[][] loc = new int[n + 2][2];
for (int i = 0; i < n + 2; i++) {
st = new StringTokenizer(br.readLine());
loc[i][0] = Integer.parseInt(st.nextToken());
loc[i][1] = Integer.parseInt(st.nextToken());
}
if (Math.abs(loc[0][0] - loc[n + 1][0]) + Math.abs(loc[0][1] - loc[n + 1][1]) <= 1000) {
sb.append("happy\n");
continue;
} else {
boolean[] visited = new boolean[n + 2];
Arrays.fill(visited, false);
s.clear();
s.push(new int[] {0, loc[0][0], loc[0][1]});
int[] tmp = new int[3];
while(!s.empty()) {
tmp = s.pop();
if (tmp[0] == n + 1)
break;
if (visited[tmp[0]])
continue;
visited[tmp[0]] = true;
for (int i = 1; i <= n + 1; i++) {
if (visited[i])
continue;
if (Math.abs(tmp[1] - loc[i][0]) + Math.abs(tmp[2] - loc[i][1]) <= 1000)
s.push(new int[] {i, loc[i][0], loc[i][1]});
}
}
if (tmp[0] == n + 1)
sb.append("happy\n");
else
sb.append("sad\n");
}
}
System.out.print(sb.toString());
}
}
출발점에서 도착점까지 가는 모든 경로 중에서 각 노드 사이의 거리가 1000 이하인 경로가 존재하는지를 판단하는 문제.
DFS, BFS, 플루이드 워셜 알고리즘 등으로 풀 수 있으며, 위 코드에서는 DFS를 사용했다.
스택 s, 불리언 배열 visited, 정수 배열 loc을 사용했다.
visited 배열에는 해당 편의점을 방문했는지 여부를 저장하고, loc 배열에는 [0]집, [1 : n] 편의점, [n + 1]페스티벌의 좌표를 각각 저장했다.
최초에 집에서 페스티벌까지 편의점을 거치지 않고 갈 수 있는지를 판단한다.
바로 갈 수 없다면 스택에 집(출발점)의 좌표를 넣고 스택이 비거나 페스티벌에 도착할 때까지 DFS로 경로를 찾는다.
https://www.acmicpc.net/problem/9205
9205번: 맥주 마시면서 걸어가기
문제 송도에 사는 상근이와 친구들은 송도에서 열리는 펜타포트 락 페스티벌에 가려고 한다. 올해는 맥주를 마시면서 걸어가기로 했다. 출발은 상근이네 집에서 하고, 맥주 한 박스를 들고 출발
www.acmicpc.net
ventania1680/algorithm
Contribute to ventania1680/algorithm development by creating an account on GitHub.
github.com
'Algorithm > BOJ' 카테고리의 다른 글
BOJ11403 / 경로 찾기 (0) | 2020.08.15 |
---|---|
BOJ10026 / 적록색약 (0) | 2020.08.14 |
BOJ9019 / DSLR (0) | 2020.08.12 |
BOJ6064 / 카잉 달력 (0) | 2020.08.11 |
BOJ1654 / 랜선 자르기 (0) | 2020.08.10 |