카테고리 없음
2024 - 08- 26 C++ 코딩테스트 10주완성 D+33
Jang_^
2024. 8. 26. 19:09
백준 2589 문제 - 보물섬
보물섬 지도를 발견한 후크 선장은 보물을 찾아나섰다.
보물섬 지도는 아래 그림과 같이 직사각형 모양이며 여러 칸으로 나뉘어져 있다.
각 칸은 육지(L)나 바다(W)로 표시되어 있다. 이 지도에서 이동은 상하좌우로 이웃한 육지로만 가능하며, 한 칸 이동하는데 한 시간이 걸린다.
보물은 서로 간에 최단 거리로 이동하는데 있어 가장 긴 시간이 걸리는 육지 두 곳에 나뉘어 묻혀있다.
육지를 나타내는 두 곳 사이를 최단 거리로 이동하려면 같은 곳을 두 번 이상 지나가거나, 멀리 돌아가서는 안 된다.
예를 들어 위와 같이 지도가 주어졌다면 보물은 아래 표시된 두 곳에 묻혀 있게 되고, 이 둘 사이의 최단 거리로 이동하는 시간은 8시간이 된다.
보물 지도가 주어질 때, 보물이 묻혀 있는 두 곳 간의 최단 거리로 이동하는 시간을 구하는 프로그램을 작성하시오.
입력
첫째 줄에는 보물 지도의 세로의 크기와 가로의 크기가 빈칸을 사이에 두고 주어진다.
이어 각각의 원소 L 또는 W 를 입력받는다. ( L은 땅, W는 바다를 의미하고, 각 행마다 띄워쓰기는 하지않는다.)
보물 지도의 가로, 세로의 크기는 각각 50이하이다.
출력
첫째 줄에 보물이 묻혀 있는 두 곳 사이를 최단 거리로 이동하는 시간을 출력한다.
실습코드
#include <bits/stdc++.h>
using namespace std;
//1. 변수목록
//맵의 최대 크기를 정의할 정수형 변수 int max_length = 54;
//맵의 행과 열의 크기를 받을 정수형 변수 int n,m;
//맵을 표현할 2차원 문자열 배열 a[max_length][max_length];
//최단거리를 비교할 땅을 담을 벡터 vector<pair<int>> land;
//방문한 곳을 표현할 2차원 정수 배열 visited[max_length][max_length]
//각 땅마다의 최단거리를 정의할 정수형 변수 min_distance
//땅마다 비교하여 최대의 거리를 저장할 정수형 변수 max_distance,ret
//땅마다의 바다의 개수를 비교하기 위한
//dy[4] = {-1,0,1,0}
//dx[4] = {0,1,0,-1}
const int max_length = 54;
int n, m, min_distance, ret;
int a[max_length][max_length],visited[max_length][max_length];
vector<int> max_distance;
vector<pair<int,int>> land;
int dy[4] = { -1, 0, 1, 0 };
int dx[4] = { 0, 1 , 0 , -1 };
//2-3-2. void dfs(int starty,int startx,int ary,int arx);
//2-3-2-1. visited[y][x] = 1;
//2-3-2-2. 4까지 반복문
//2-3-2-2-1. int ny = y + dy[i];
//2-3-2-2-2. int nx = x + dx[i];
//2-3-2-2-3. if(ny < 0 || ny >= n || nx < 0 || nx >= m)
//2-3-2-2-3-1 continue;
//2-3-2-2-4. if(!visited[ny][nx] && a[ny][nx] == 'L')
//2-3-2-2-4-1. min_distance++;
//2-3-2-2-4-2. dfs(ny,nx,ary,arx);
//2-3-2-2-4-3. if(min_distance < max _distance) max_distance = min_distance;
//2-3-2-2-4-4. min_distance = 0;
//2-3-2-2. 4까지 반복문 종료
//2-3-2. dfs(int starty,int startx,int ary,int arx) 함수 설명 종료
void dfs(int y, int x, int ary, int arx)
{
visited[y][x] = 1;
if (y == ary && x == arx)
{
max_distance.push_back(min_distance);
return;
}
for (int i = 0; i < 4; i++)
{
int ny = y + dy[i];
int nx = x + dx[i];
if (ny < 0 || ny >= n || nx < 0 || nx >= m)
continue;
if (!visited[ny][nx] && a[ny][nx] == 'L')
{
min_distance++;
dfs(ny, nx, ary, arx);
}
}
return;
}
int main()
{
//2. 알고리즘
//2-1. 보물섬 지도의 열과 행을 입력받는다.
cin >> n >> m;
//2-1-1 max_distance = n * m
ret = n * m;
//2-2. 보물섬 지도의 열의 길이만큼 반복문
//2-2-1. 임시 문자열 str을 선언하고 입력받는다.
//2-2-2. 보물섬 지도의 행만큼 반복문
//2-2-2-1. a[i][j] =str[j]
//2-2-2-1. int cnt = 0;
//2-2-2-2. i=0 부터 4까지 반복
//2-2-2-2-1. int ny = i + dy; int nx = j + dx;
//2-2-2-2-2. if(ny < 0 || ny >= n || nx < 0 || nx >= m || a[ny][nx] == 'W')
//2-2-2-2-3. cnt++;
//2-2-2-2. i=0 부터 4까지 반복문종료
//2-2-2-3. if(cnt > 3)
//2-2-2-3-1 land.push_back({i,j});
//2-2-2. 보물섬 지도의 행만큼 반복문 종료
for (int i = 0; i < n; i++)
{
string str;
cin >> str;
for (int j = 0; j < m; j++)
{
a[i][j] = str[j];
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
int cnt = 0;
if (a[i][j] = 'L')
{
for (int k = 0; k < 4; k++)
{
int ny = i + dy[k];
int nx = j + dx[k];
if (ny < 0 || ny >= n || nx < 0 || nx >= m || a[ny][nx] == 'W')
cnt++;
}
}
if (cnt >= 3)
land.push_back({ i,j });
}
}
//2-2. 보물섬 지도의 열의 길이만큼 반복문 종료
//2-3. for(int i : land)
//2-3-1. int min_cnt = 0;
//2-3-2. void dfs(land[i].first, land[i].second, land[i + 1].first, land[i + 1].second);
//2-3-3. fill(visited[0][0],n*m,0);
//2-3-4. if(max_distance > ret) ret = max_distance
if (land.size() > 0)
{
for (int i = 0; i < land.size() - 1; i++)
{
int m_min_distance = n * m;
dfs(land[i].first, land[i].second, land[i + 1].first, land[i + 1].second);
fill(&visited[0][0], &visited[n][m], 0);
for (int i : max_distance)
{
if (min_distance > i)
{
min_distance = i;
}
}
if (m_min_distance > ret)
ret = m_min_distance;
max_distance.clear();
min_distance = 0;
}
}
//2-3. for(int i : land) 종료
cout << ret;
return 0;
//2-4. cout << ret;
}
예제 출력이 안된다.. ㅠ 한번 더 코드를 반복 숙달해보아야겠다.
여러번 코드를 수정해보았으나,, 심신미약 상태로 자꾸 빠져버리므로 해설을 보며 마음의 정화를 시도하자
#include<bits/stdc++.h>
using namespace std;
int n, m, mx, visited[54][54];
const int dy[] = {-1, 0, 1, 0};
const int dx[] = {0, 1, 0, -1};
char a[54][54];
void bfs(int y, int x){
memset(visited, 0, sizeof(visited));
visited[y][x] = 1;
queue<pair<int, int>> q;
q.push({y, x});
while(q.size()){
tie(y, x) = q.front(); q.pop();
for(int i = 0; i < 4; i++){
int ny = y + dy[i];
int nx = x + dx[i];
if(ny < 0 || ny >= n || nx < 0 || nx >= m) continue;
if(visited[ny][nx]) continue;
if(a[ny][nx] == 'W')continue;
visited[ny][nx] = visited[y][x] + 1;
q.push({ny, nx});
mx = max(mx, visited[ny][nx]);
}
}
return;
}
int main(){
cin >> n >> m;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> a[i][j];
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(a[i][j] == 'L') bfs(i, j);
}
}
cout << mx - 1 << "\n";
}
정말 간단하게 방문할때마다 visited 를 증감해주어 제일 높은 Max값을 출력해주면 최장거리이다..!!
너무 깊게 생각해서 잘 안풀렸나보다.. ㅠ