[C++] SWEA 1249번: 보급로

2022. 12. 22. 17:33·problem solving/SWEA

🔗 문제

SW Expert Academy

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

🖍 풀이

DFS는 시간초과고 BFS이라고 생각해서 풀면 오답이다. (경험담)

 

왜냐하면 생각해보면 map의 좌표 (x, y)까지 오는 경로는 다양하다.

가는 길이 0, 1로만 이루어진 것이 아니기 때문에 첫 방문이 최소 경로라고 단정지을 수 없다.

 

그래서 상하좌우로 이동하면서 (x, y)까지 걸린 시간을 계속해서 갱신해주어야 한다.

visited[x][y]로 재방문를 판단하기는 하지만 그냥 갱신인지 신규인지만 판단하는 용도로 사용해줬다.

  • 다익스트라의 개념을 알고 있으면 내 풀이를 이해하는데 도움됨

 

💾  소스

#include <iostream>
#include <memory.h>
#include <queue>

const int MAX = 100+2;
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};

int map[MAX][MAX] = {0, };
int N, answer = 1e9;

typedef  std::pair<int, int> pii;

bool isValid(const int x, const int y)
{
    if(x<0 || y<0 || x>=N || y>=N)
        return false;
    
    return true;
}

void solve()
{
    std::queue<pii> q;
    q.push({0, 0});
    
    
    bool visited[MAX][MAX] = {false, };
    visited[0][0] = true;
    
    
    int dp[MAX][MAX] = {0, };
    dp[0][0] = 0;
    
    
    while(!q.empty())
    {
        int nowX = q.front().first;
        int nowY = q.front().second;

        if(nowX == N-1 && nowY == N-1)
        {
            answer = std::min(answer, dp[N-1][N-1]);
        }
        q.pop();
        
        if(answer <= dp[nowX][nowY])
            continue;
        
        for(int d=0; d<4; ++d)
        {
            int x = nowX + dx[d];
            int y = nowY + dy[d];
            
            if(isValid(x, y) == false)
                continue;
            
            **// 더 낮은 가중치 발견하면 갱신하기
            if(visited[x][y])
            {
                if(dp[x][y] > dp[nowX][nowY] + map[x][y])
                {
                    q.push({x, y});
                    dp[x][y] = dp[nowX][nowY] + map[x][y];
                }
            }
            else
            {
                dp[x][y] = dp[nowX][nowY] + map[x][y];
                q.push({x, y});
                visited[x][y] = true;
            }**

        }
    }
}

int main()
{
    int T; char c;
    std::cin >> T;
    
    for(int tc=1; tc<=T; ++tc)
    {
        std::cin >> N;
        for(int i=0; i<N; ++i)
        {
            for(int j=0; j<N; ++j)
            {
                std::cin >> c;
                map[i][j] = c-'0';
            }
        }
        
        answer = 1e9;
        solve();
        std::cout << '#' << tc <<' ' << answer << '\\n';
    }
    return 0;
}
저작자표시 비영리 변경금지
'problem solving/SWEA' 카테고리의 다른 글
  • [C++] SWEA 1258번: 행렬찾기
  • [C++] SWEA 1251번: 단순도금비용
  • [C++] SWEA 1257번: K번째 문자열 (set 활용)
  • [C++] SWEA 1244번: 최대상금
u1qns
u1qns
그냥 알고리즘 풀이만 올리려고 했는데, 정보 찾다보니까 너무 답답해서 이것저것 쓰다보니 커졌어요.
  • u1qns
    블로그
    u1qns
  • 전체
    오늘
    어제
    • 분류 전체보기 (170) N
      • 회고 (1)
      • programming (17)
        • 개념 정리 (6)
        • CI CD (1)
        • 트러블 슈팅 (0)
        • 환경설정 및 팁 (7)
      • problem solving (152) N
        • 개념 정리 (3)
        • 백준 (126) N
        • SWEA (15)
        • 프로그래머스 (4)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    완전탐색
    HELLOSSAFY
    SSAFY수료식
    SWEA
    cpp
    되추적
    cmath
    삼성청년SW아카데미
    DP
    C++
    boj
    DFS
    SSAFY
    미해결
    POW
    그리디
    구현
    BFS
    투포인터
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
u1qns
[C++] SWEA 1249번: 보급로
상단으로

티스토리툴바