ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2024 - 08- 26 C++ 코딩테스트 10주완성 D+33
    카테고리 없음 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값을 출력해주면 최장거리이다..!!

     

    너무 깊게 생각해서 잘 안풀렸나보다.. ㅠ 

     

Designed by Tistory.