티스토리 뷰
1. 문제
https://www.acmicpc.net/problem/2842
2842번: 집배원 한상덕
상덕이는 언덕 위에 있는 마을의 우체국에 직업을 얻었다. 마을은 N×N 행렬로 나타낼 수 있다. 행렬로 나뉘어진 각 지역은 우체국은 'P', 집은 'K', 목초지는 '.' 중 하나로 나타낼 수 있다. 또, 각
www.acmicpc.net
2. 풀이
투포인터와 BFS를 모두 활용한다.
- 구해야 되는 것은 가장 작은 고도의 차이므로, 가장 높은 고도(high)와 가장 낮은 고도(low)를 설정해 그 고도 내에서 집배원이 모든 집을 방문할 수 있는지 본다. 투포인터를 이용해 low 값 과 high 값을 변경해가며 가장 작은 고도차를 찾는다.
- 고도 내에서 모든 집을 방문할수 있는지 확인 할 때 BFS를 사용한다. BFS로 지도를 이동하면서 방문한 집의 개수를 확인한다.
3. 코드
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main_2842 {
static char[][] map; // 위치 저장
static int n, pX, pY; // 우체국 위치
static int[][] pirodo; // 피로도
static int hCnt; // 집 개수
static int[][] dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {-1, -1}, {1, -1}, {-1, 1}};
// 범위 내에 있는지 확인
public static boolean isInRange(int x, int y) {
if(x < 0 || x >= n || y < 0 || y >= n) return false;
return true;
}
// low ~ high의 피로도 사이로 탐색을 했을때, 배달 할 수 있는 집의 개수를 리턴
public static int bfs(int low, int high) {
int houseCnt = 0;
Queue<int[]> q = new LinkedList<>();
boolean[][] visited = new boolean[n][n];
if(pirodo[pX][pY] < low || pirodo[pX][pY] > high)
return -1;
q.add(new int[] {pX, pY});
visited[pX][pY] = true;
while(!q.isEmpty() && houseCnt < hCnt) {
int[] nowPos = q.poll();
for(int i = 0; i < 8; i++) {
int newX = nowPos[0] + dir[i][0];
int newY = nowPos[1] + dir[i][1];
if(!isInRange(newX, newY) || visited[newX][newY]) continue;
if(pirodo[newX][newY] < low || pirodo[newX][newY] > high) continue;
visited[newX][newY] = true;
q.add(new int[] {newX, newY});
if(map[newX][newY] == 'K')
houseCnt++;
}
}
return houseCnt;
}
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
map = new char[n][n];
pirodo = new int[n][n];
for(int i = 0; i < n; i++) {
String s = br.readLine();
map[i] = s.toCharArray();
for(int j = 0; j < n; j++) {
if(s.charAt(j) == 'P') {
pX = i; pY = j;
}else if(s.charAt(j) == 'K') {
hCnt++;
}
}
}
ArrayList<Integer> hList = new ArrayList<Integer>();
StringTokenizer st;
for(int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for(int j = 0; j < n; j++) {
pirodo[i][j] = Integer.parseInt(st.nextToken());
hList.add(pirodo[i][j]);
}
}
// 투포인터로 낮은 높이, 높은 높이를 지정해 그 높이 안에서 모든 집에 배달 할 수 있는지를 확인
// 모든 집에 배달 할 수 있으면 정답
Collections.sort(hList);
int answer = hList.get(hList.size() - 1) - hList.get(0); // max
int low = 0, high = 0;
while(low <= high && low < hList.size() && high < hList.size()) {
// 낮은 높이, 높은 높이를 지정해 그 높이 안에서 모든 집에 배달 할 수 있는지를 확인 --> bfs
if(bfs(hList.get(low), hList.get(high)) == hCnt) {
int tmp = hList.get(high) - hList.get(low);
if(tmp < answer) answer = tmp;
low++;
}else {
high++;
}
}
System.out.println(answer);
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[JAVA/백트래킹] 백준 9663 N-Queen (0) | 2021.07.11 |
---|---|
[JAVA/Binary Search] 백준 1072 게임 (0) | 2021.07.08 |
[JAVA/투포인터] 백준 7453 합이 0인 네 정수 (0) | 2021.07.08 |
[JAVA/Deque] 백준 11003 최솟값 찾기 (0) | 2021.07.07 |
[C++/구현] 백준 9093 단어 뒤집기 (0) | 2020.01.29 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 키 순서
- BFS
- mysql
- git
- hackerrank
- dovecot
- 구슬 탈출2
- 블루투스
- the pads
- java
- 스티커모으기2
- 프로그래머스
- 11503
- dht11
- 자바
- 라즈비안
- 메일서버
- FTP
- 합승 택시 요금
- hc-06
- 아두이노
- 리눅스
- DP
- 백준
- ESP8266
- 집배원 한상덕
- 워드프레스
- 라즈베리파이
- c++
- 2981
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함