일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 스택
- DP
- 그리디
- 배열
- Java
- 빅데이터
- HashMap
- 백트래킹
- 프로그래머스
- 알고리즘
- 새벽코딩
- Queue
- 아스키코드
- 완전탐색
- BufferedReader
- 다이나믹프로그래밍
- 구현
- 브루트포스
- BFS
- oracle
- 다리 만들기
- Stack
- SQL
- 시뮬레이션
- LIS
- 문자열
- 탐색
- Python
- dfs
- 백준
- Today
- Total
새벽코딩
[백준] [9205] 맥주 마시면서 걸어가기 본문
https://www.acmicpc.net/problem/9205
9205번: 맥주 마시면서 걸어가기
송도에 사는 상근이와 친구들은 송도에서 열리는 펜타포트 락 페스티벌에 가려고 한다. 올해는 맥주를 마시면서 걸어가기로 했다. 출발은 상근이네 집에서 하고, 맥주 한 박스를 들고 출발한다.
www.acmicpc.net
문제
송도에 사는 상근이와 친구들은 송도에서 열리는 펜타포트 락 페스티벌에 가려고 한다. 올해는 맥주를 마시면서 걸어가기로 했다. 출발은 상근이네 집에서 하고, 맥주 한 박스를 들고 출발한다. 맥주 한 박스에는 맥주가 20개 들어있다. 목이 마르면 안되기 때문에 50미터에 한 병씩 마시려고 한다. 즉, 50미터를 가려면 그 직전에 맥주 한 병을 마셔야 한다.
상근이의 집에서 페스티벌이 열리는 곳은 매우 먼 거리이다. 따라서, 맥주를 더 구매해야 할 수도 있다. 미리 인터넷으로 조사를 해보니 다행히도 맥주를 파는 편의점이 있다. 편의점에 들렸을 때, 빈 병은 버리고 새 맥주 병을 살 수 있다. 하지만, 박스에 들어있는 맥주는 20병을 넘을 수 없다. 편의점을 나선 직후에도 50미터를 가기 전에 맥주 한 병을 마셔야 한다.
편의점, 상근이네 집, 펜타포트 락 페스티벌의 좌표가 주어진다. 상근이와 친구들이 행복하게 페스티벌에 도착할 수 있는지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수 t가 주어진다. (t ≤ 50)
각 테스트 케이스의 첫째 줄에는 맥주를 파는 편의점의 개수 n이 주어진다. (0 ≤ n ≤ 100).
다음 n+2개 줄에는 상근이네 집, 편의점, 펜타포트 락 페스티벌 좌표가 주어진다. 각 좌표는 두 정수 x와 y로 이루어져 있다. (두 값 모두 미터, -32768 ≤ x, y ≤ 32767)
송도는 직사각형 모양으로 생긴 도시이다. 두 좌표 사이의 거리는 x 좌표의 차이 + y 좌표의 차이 이다. (맨해튼 거리)
출력
각 테스트 케이스에 대해서 상근이와 친구들이 행복하게 페스티벌에 갈 수 있으면 "happy", 중간에 맥주가 바닥나서 더 이동할 수 없으면 "sad"를 출력한다.
예제 입력 1 복사
2
2
0 0
1000 0
1000 1000
2000 1000
2
0 0
1000 0
2000 1000
2000 2000
예제 출력 1 복사
happy
sad
※ JAVA 코드
import java.io.*;
import java.util.*;
public class Main {
static int n;
// 맥주의 개수
static int beer = 20;
// 50미터
static final int DISTANCE = 1000;
// 좌표를 담을 리스트
static ArrayList<Node> point;
static ArrayList<ArrayList<Integer>> list;
static boolean [] visited;
// 좌표를 담을 노드
static class Node {
int x, y;
Node(int x, int y){
this.x = x;
this.y = y;
}
}
// 두 노드의 거리측정
static int distance(Node s, Node e) {
return Math.abs(e.x - s.x) + Math.abs(e.y - s.y);
}
static boolean BFS(ArrayList<ArrayList<Integer>> l, int num) {
Queue<Integer> q = new LinkedList<>();
// 초기점 거리 0
q.offer(0);
visited[0] = true;
while(q.isEmpty() == false) {
int now = q.poll();
// 정점에 도착하면 true;
if(now == num+1) {
return true;
}
for(int i : l.get(now)) {
if(visited[i] == false) {
visited[i] = true;
q.offer(i);
}
}
}
return false;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
// 테스트케이스
int t = Integer.parseInt(br.readLine());
while(t > 0) {
// 편의점 개수
n = Integer.parseInt(br.readLine());
point = new ArrayList<>();
// 방문체크용도
visited = new boolean[n + 2];
// 좌표
for(int i = 0; i < n + 2; i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
// 집, 편의점, 도착지 좌표를 담는다
point.add(new Node(x, y));
}
list = new ArrayList<>();
for(int i = 0; i < n + 2; i++) {
list.add(new ArrayList<>());
}
// 두 지점의 연결 (모든 정점을 연결한다)
for(int i = 0; i < n + 2; i++) {
for(int j = i + 1; j < n + 2; j++) {
// 두정점간의 거리가 1000m이하만 담는다.
if(distance(point.get(i), point.get(j)) <= DISTANCE) {
list.get(i).add(j);
list.get(j).add(i);
}
}
}
boolean canGo = BFS(list, n);
System.out.println(canGo == true ? "happy" : "sad");
t--;
}
}
}
※ 생각정리
기존 BFS문제들과 매우 유사해 보였지만 조금 차이가 있었다. 각 노드의 좌표를 Node 클래스에 담고 탐색을 실행하기 전에 노드들간의 연결이 이루어져있는지 확인한다. 이때 맥주20캔이 사용될 수 있는 최대거리 1000m로 제한을 둔다.
만약, 두 정점의 거리가 1000m가 넘으면 리스트를 잇지 않는다. 해당 연결리스트를 ArrayList에 담고 BFS 알고리즘을 돌린다.
정점의 개수가 끝에 다달았다면 성공 (happy 출력), 닿지 못하고 큐가 빈다면 실패 (sad 출력)
-새벽코딩-
'알고리즘' 카테고리의 다른 글
[백준] [10708] 크리스마스 파티 (0) | 2022.12.25 |
---|---|
[백준] [1926] 그림 (0) | 2022.12.22 |
[백준] [14502] 연구소 (JAVA) (DFS, BFS) (0) | 2022.12.15 |
[백준] [9461] 파도반 수열 (JAVA) (DP) (2) | 2022.12.14 |
[백준] [5567] 결혼식 (JAVA) (0) | 2022.12.14 |