코딩 공부/백준(C++)

[백준 14497][C++] 주난이의 난(難)

2023. 10. 21. 15:05
목차
  1. ◆문제 해결 및 설명◆
  2. ◆코드 전문◆

문제 링크

https://www.acmicpc.net/problem/14497

 

14497번: 주난의 난(難)

주난이는 크게 화가 났다. 책상 서랍 안에 몰래 먹으려고 숨겨둔 초코바가 사라졌기 때문이다. 주난이는 미쳐 날뛰기 시작했다. 사실, 진짜로 뛰기 시작했다. ‘쿵... 쿵...’ 주난이는 점프의 파

www.acmicpc.net

 


◆문제 해결 및 설명◆

문제 해설 : 생략

말이 좀 어려워서 애를 먹었는데(잘못된거 같기도) 예제를 보면 주난이와 이어진 0들의의 상하좌우를 0으로 만들어준다.

입력 예제 1번을 그림을 통해 표현해 보았다. 3번뛰면 (0,1)이 지워지면서 정답임을 알 수 있다.

일단, 교실의 정보를 저장할 변수 mapS과 위치정보(y10, x1, y2, x2)를 저장하고, 교실의 입력이 문자열로 되어있어 이를 int형식 map으로 변환해주었다. 주난이와 도둑은 0과 1로 변환했다.

int main()
{
    cin >> n >> m;
    cin >> y10 >> x1 >> y2 >> x2;
    y10--, x1--, y2--, x2--;

    mapS = vector<string>(n);
    map = vector<vector<int>>(n, vector<int>(m));
    cin.ignore();
    for (int i = 0; i < n; i++)
    {
        getline(cin, mapS[i]);
    }
    mapS[y10][x1] = '0';
    mapS[y2][x2] = '1';

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            map[i][j] = mapS[i][j] - '0';
        }
    }
	...

 

이 문제를 풀기위해 주난이가 뛸때마다. 다익스트라를 사용하였다.

1e8으로 초기화된 거리를 저장할 distanceMap을 만들어서, 상하좌우로 갔을때, 주난이가 갈 수 있는 최단거리를 구하였다.

도둑이 0으로 바뀌었을때 주난이가 뛴 횟수를 출력하고 프로그램을 종료시켰다.

    int cnt = 0;
    while (1)
    {
        // Initialize variables
        distanceMap = vector<vector<int>>(n, vector<int>(m, 1e8));
        
        cnt++;
        dijkstra(0, y10, x1);
        if (map[y2][x2] == 0)
        {
            cout << cnt;
            return 0;
        }
    }

이차원 배열 맵의 특수성을 감안하여, 우선순위 큐를 이용하여 다익스트라를 구현하였다. 

if (distance + map[ny][nx] < distanceMap[ny][nx]) 라면  distanceMap[ny][nx]을 갱신하고 que에 저장을 해주었다.

void dijkstra(int dist, int row, int col)
{
    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> que;
    que.push({dist, row, col});

    while (!que.empty())
    {
        int distance;
        tie(distance, row, col) = que.top();
        que.pop();

        for (int i = 0; i < 4; i++)
        {
            int ny = row + dxy[i];
            int nx = col + dxy[3 - i];

            if (ny < 0 || ny >= n || nx < 0 || nx >= m)
            {
                continue;
            }
            if (distance + map[ny][nx] < distanceMap[ny][nx])
            {
                distanceMap[ny][nx] = distance + map[ny][nx];
                que.push({distanceMap[ny][nx], ny, nx});
            }
        }
    }

 

이후 distanceMap에 저장된 최단거리가 1이하라면 주난이의 파동이 닫는 위치임으로 해당 위치의 map을 0으로 바꿔 주었다.

	...
	// change map
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (distanceMap[i][j] <= 1)
            {
                map[i][j] = 0;
            }
        }
    }
    
    return;
}

 

이를 반복하면 몇번만에 끝낼 수 있었는지 확인할 수 있다.

◆코드 전문◆

#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
int n, m, x1, y10, x2, y2;
vector<string> mapS;
vector<vector<int>> map;
vector<vector<int>> distanceMap;
int dxy[]{1, -1, 0, 0};

void dijkstra(int dist, int row, int col)
{
    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> que;
    que.push({dist, row, col});

    while (!que.empty())
    {
        int distance;
        tie(distance, row, col) = que.top();
        que.pop();

        for (int i = 0; i < 4; i++)
        {
            int ny = row + dxy[i];
            int nx = col + dxy[3 - i];

            if (ny < 0 || ny >= n || nx < 0 || nx >= m)
            {
                continue;
            }
            if (distance + map[ny][nx] < distanceMap[ny][nx])
            {
                distanceMap[ny][nx] = distance + map[ny][nx];
                que.push({distanceMap[ny][nx], ny, nx});
            }
        }
    }

    // change map
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (distanceMap[i][j] <= 1)
            {
                map[i][j] = 0;
            }
        }
    }

    return;
}

int main()
{
    cin >> n >> m;
    cin >> y10 >> x1 >> y2 >> x2;
    y10--, x1--, y2--, x2--;

    mapS = vector<string>(n);
    map = vector<vector<int>>(n, vector<int>(m));
    cin.ignore();
    for (int i = 0; i < n; i++)
    {
        getline(cin, mapS[i]);
    }
    mapS[y10][x1] = '0';
    mapS[y2][x2] = '1';

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            map[i][j] = mapS[i][j] - '0';
        }
    }

    int cnt = 0;
    while (1)
    {
        // Initialize variables
        distanceMap = vector<vector<int>>(n, vector<int>(m, 1e8));

        cnt++;
        dijkstra(0, y10, x1);
        if (map[y2][x2] == 0)
        {
            cout << cnt;
            return 0;
        }
    }
}

'코딩 공부 > 백준(C++)' 카테고리의 다른 글

[백준 10798][C++] 세로읽기  (0) 2023.10.28
[백준 4781][C++] 사탕 가게  (0) 2023.10.26
[백준 13549][C++] 알파벳  (1) 2023.10.21
[백준 1245][C++] 농장 관리  (0) 2023.10.21
[백준 1987][C++] 알파벳  (1) 2023.09.14
  • ◆문제 해결 및 설명◆
  • ◆코드 전문◆
'코딩 공부/백준(C++)' 카테고리의 다른 글
  • [백준 10798][C++] 세로읽기
  • [백준 4781][C++] 사탕 가게
  • [백준 13549][C++] 알파벳
  • [백준 1245][C++] 농장 관리
메카인
메카인
메카인
메카인의 지식창고
메카인
전체
오늘
어제
  • 분류 전체보기
    • 코딩 공부
      • TIL(Today I Learn)
      • TIL
      • 백준(C++)
      • Python
      • 알고리즘
      • 프로젝트 회고
    • C++
      • C++
      • C++ STL
      • C,C++ mCoding yotube
    • 게임개발
      • 언데드서바이벌_골드메탈_클론코딩
      • 3D_골드메탈_클론코딩
      • 유니티_문제해결
      • 게임 수학
    • Unreal 공부
      • UE5 GameDev
      • Unreal Engine 4 C++ The Ult..
    • 교재 문제 풀이
      • 운영체제
    • 정보처리기사
      • 정처기 요약
      • 정처기 오답노트
    • 학교수업
      • 데이터베이스
      • 프로그래밍 언어론
      • 리눅스 시스템
      • 네트워크
    • 일상
      • 주식
      • 독서
    • (비공개 전용)
      • memory
      • Build
      • OOP
      • Smart Pointer
      • lamda
      • 게임 수학
      • 모던 C++
      • 모던 C++ STL
      • 모던 C++ Concurrency, Paralle..

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기
  • 블로그 관리

공지사항

  • 공지사항 - 인생과 블로그의 목표

인기 글

태그

최근 댓글

최근 글

hELLO · Designed By 정상우.
메카인
[백준 14497][C++] 주난이의 난(難)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.