상세 컨텐츠

본문 제목

1261. 알고스팟

알고리즘/백준

by 아리따운노을 2020. 1. 13. 00:46

본문

블로그 하고는 처음으로 푸는 백준 문제다. 오랜만에 풀었더니 인풋 방법이 아예 삼성과 달라서 버벅 버벅...

인풋 하는데 조금 오래 걸렸다.

문제부터 보자


문제

알고스팟 운영진이 모두 미로에 갇혔다. 미로는 N*M 크기이며, 총 1*1크기의 방으로 이루어져 있다. 미로는 빈 방 또는 벽으로 이루어져 있고, 빈 방은 자유롭게 다닐 수 있지만, 벽은 부수지 않으면 이동할 수 없다.

알고스팟 운영진은 여러명이지만, 항상 모두 같은 방에 있어야 한다. 즉, 여러 명이 다른 방에 있을 수는 없다. 어떤 방에서 이동할 수 있는 방은 상하좌우로 인접한 빈 방이다. 즉, 현재 운영진이 (x, y)에 있을 때, 이동할 수 있는 방은 (x+1, y), (x, y+1), (x-1, y), (x, y-1) 이다. 단, 미로의 밖으로 이동 할 수는 없다.

벽은 평소에는 이동할 수 없지만, 알고스팟의 무기 AOJ를 이용해 벽을 부수어 버릴 수 있다. 벽을 부수면, 빈 방과 동일한 방으로 변한다.

만약 이 문제가 알고스팟에 있다면, 운영진들은 궁극의 무기 sudo를 이용해 벽을 한 번에 다 없애버릴 수 있지만, 안타깝게도 이 문제는 Baekjoon Online Judge에 수록되어 있기 때문에, sudo를 사용할 수 없다.

현재 (1, 1)에 있는 알고스팟 운영진이 (N, M)으로 이동하려면 벽을 최소 몇 개 부수어야 하는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 미로의 크기를 나타내는 가로 크기 M, 세로 크기 N (1 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 미로의 상태를 나타내는 숫자 0과 1이 주어진다. 0은 빈 방을 의미하고, 1은 벽을 의미한다.

(1, 1)과 (N, M)은 항상 뚫려있다.

출력

첫째 줄에 알고스팟 운영진이 (N, M)으로 이동하기 위해 벽을 최소 몇 개 부수어야 하는지 출력한다.



문제는 이렇다. N*M 행렬이 주어지고 1,1에서 N,M 까지 도달하는데 방문하는 최소한의 1의 개수를 출력하는 문제다.

처음에는 아무 생각 없이 DFS로 풀어야지 했는데 막상 구현하니 6*6에서도 시간이 꽤 걸려 BFS로 풀었다.

DFS는 최소 길 찾는데 쓰면 안된다는걸 다시 생각나게 하는 계기였다.

알고리즘 생각은

1.각 거리를 MAX로 설정해 놓고 1,1의 거리를 0으로 설정.

2. 4방향 탐색을 하면서 1이면 거리를 +, 0이면 거리 그대로, 가는 곳의 거리와 현재 거리를 비교해서 갱신

3. M,N 출력

BFS 코드를 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <queue>
using namespace std;
 
int MAP[101][101], moveX[]={-1,0,1,0}, moveY[]={0,1,0,-1}, dist[101][101];
int cnt,N,M;
void bfs()
{
    queue<pair<intint> > q;
    q.push(make_pair(1,1));
    dist[1][1= 0;
    while(!q.empty())
    {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for(int i=0;i<4;i++)
        {
            int mx = x + moveX[i];
            int my = y + moveY[i];
            if(mx<1||my<1||mx>M||my>N) continue;
            if(MAP[mx][my]==1)
            {
                if(dist[mx][my]>dist[x][y]+1)
                {
                    dist[mx][my]=dist[x][y]+1;
                    q.push(make_pair(mx,my));
                }
            }
            else{
                if(dist[mx][my] > dist[x][y])
                {
                    dist[mx][my] = dist[x][y];
                    q.push(make_pair(mx,my));
                }
            }
        }
    }
 
}
int main()
{
    cin.tie(NULL);
    cout.tie(NULL);
    ios_base::sync_with_stdio(false);
    cin>>N>>M;
    cnt = 99999999;
    for (int i = 1; i <= M; i++)
    {
        string Inp;
        cin >> Inp;
        for (int j = 1; j <= Inp.length(); j++)
        {
            MAP[i][j] = Inp[j-1- '0';
            dist[i][j] = 99999999;
        }
    }
    bfs();
    cout<<dist[M][N]<<'\n';
    return 0;
}
 
cs

dn


+++++

멍청하게 처음 짠 DFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <string.h>
using namespace std;
 
int MAP[101][101], moveX[]={-1,0,1,0}, moveY[]={0,1,0,-1};
bool check[101][101];
int cnt,N,M;
void dfs(int x, int y, int dep)
{
    if (x==M&&y==N)
    {
        if (cnt > dep)
        {
            cnt = dep;
            return;
        }
    }
    for(int i=0;i<4;i++)
    {
        int mx = x + moveX[i];
        int my = y + moveY[i];
        if(mx<1||my<1||mx>M||my>N||check[mx][my]) continue;
        if (MAP[mx][my] == 1)
        {
            check[mx][my] = true;
            dfs(mx, my, dep + 1);
            check[mx][my] = false;
        }
 
        else
        {
            check[mx][my] = true;
            dfs(mx, my, dep);
            check[mx][my] = false;
        }
 
    }
}
int main()
{
    cin.tie(NULL);
    cout.tie(NULL);
    ios_base::sync_with_stdio(false);
    cin>>N>>M;
    cnt = 99999;
    for (int i = 1; i <= M; i++)
    {
        string Inp;
        cin >> Inp;
        for (int j = 1; j <= Inp.length(); j++)
        {
            MAP[i][j] = Inp[j-1- '0';
        }
    }
 
    dfs(1,1,0);
    cout<<cnt<<'\n';
    return 0;
}
 
cs


아 그리고 또 백준 제출 하면서 생각 났는데 

queue<pair<int, int> > q를 할 때 >>들의 사이를 띄어쓰기 해야한다. 하지 않으면 IDE에서는 돌아가도 백준에서는 컴파일 에러가 난다.




'알고리즘 > 백준' 카테고리의 다른 글

10610. 30  (0) 2020.02.01
7576. 토마토  (0) 2020.01.20
2749. 피보나치 수 3  (0) 2020.01.19
9020. 골드바흐의 추측  (0) 2020.01.19
1149. RGB거리 성공  (0) 2020.01.15

관련글 더보기

댓글 영역