danbibibi
article thumbnail

1. 문제

문제 바로가기> BOJ 2842번 : 집배원 한상덕

 

2842번: 집배원 한상덕

상덕이는 언덕 위에 있는 마을의 우체국에 직업을 얻었다. 마을은 N×N 행렬로 나타낼 수 있다. 행렬로 나뉘어진 각 지역은 우체국은 'P', 집은 'K', 목초지는 '.' 중 하나로 나타낼 수 있다. 또, 각

www.acmicpc.net

 

2. 풀이

고도를 ±1 씩 모든 경우의 수를 구할 경우 시간 초과가 발생한다. 50*50*1,000,000 = 2,500,000,000 (25억,,)

하지만 실제 고도의 개수는 50*50 = 2500을 초과할 수 없고, 이를 반영해서 "투 포인터 + 그래프 탐색"으로 풀었다.

 

1. 투포인터를 이용하기 위해 고도를 정렬해야 한다.

   이때, 중복되는 값은 필요 없으므로!! set을 이용해서 중복되는 값을 제거해주었다.

 

2. 투포인터를 이용해서 (low ~ high) 고도 내에서 모든 집에배달이 가능한지 확인한다.

    배달이 불가한 경우, high를 올려준다! (엇? 넘을 수없는 문턱이 있어,,! 배달 불가야!)

    배달이 가능한 경우, low를 올려준다! (어라? 피로도 더 줄일 수 있을 거 같은데? 라는 마인드로!)

 

    ++ 우체국에서 출발하므로, 우체국의 고도는 반드시 포함되어야 한다!

    

 

<cpp />
#include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<set> #define MAX 51 #define INF 1000001 using namespace std; int N; int py, px; int home_cnt=0; set<int> setAltitude; vector<int> vecAltitude; char town[MAX][MAX]; bool visited[MAX][MAX]; int altitude[MAX][MAX]; int dy[] = {0, -1, -1, -1, 0, 1, 1, 1}; int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1}; void input(){ cin >> N; string line; for(int i=0; i<N; i++){ cin >> line; for(int j=0; j<N; j++) { town[i][j] = line[j]; if(town[i][j] == 'P') {py=i; px=j;} else if(town[i][j] == 'K') home_cnt++; } } for(int i=0; i<N; i++){ for(int j=0; j<N; j++){ cin >> altitude[i][j]; setAltitude.insert(altitude[i][j]); } } for(auto iter : setAltitude) vecAltitude.push_back(iter); sort(vecAltitude.begin(), vecAltitude.end()); } int dfs(int y, int x, int low, int high){ visited[y][x] = true; int cnt = 0; for(int d=0; d<8; d++){ int ny = y+dy[d]; int nx = x+dx[d]; if(ny<0 || ny>=N || nx<0 || nx>=N || visited[ny][nx]) continue; // 범위를 벗어난 경우, 이미 방문한 경우 if(altitude[ny][nx]<low || altitude[ny][nx]>high) continue; // 범위 내 고도에서 방문 불가한 경우 if(town[ny][nx] == 'K') cnt++; cnt+=dfs(ny, nx, low, high); } return cnt; } void solution(){ // 가장 작은 피로도 int l=0, r=0, ans=INF; while (r < vecAltitude.size()) { int low = vecAltitude[l], high=vecAltitude[r]; if(altitude[py][px]<low || altitude[py][px]>high) { r++; continue;} // 우체국 고도를 포함하지 않는 경우 (우체국에서 출발) memset(visited, false, sizeof(visited)); if(dfs(py, px, low, high)==home_cnt){ ans = min(ans, high-low); l++; } else r++; } cout << ans; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); input(); solution(); }

'문제 풀이 > 백준' 카테고리의 다른 글

BOJ 1584번: 게임  (0) 2023.03.18
BOJ 2636번: 치즈  (0) 2023.03.18
BOJ 1918번: 후위 표기식  (0) 2023.03.07
BOJ 21758번: 꿀 따기  (0) 2023.02.25
BOJ16946번: 벽 부수고 이동하기 4  (0) 2023.02.25
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로