백준의 로봇(1726) 문제이다.

( 문제 바로가기 )


[ 문제풀이 ]

1) 기본적인 BFS/DFS 문제이지만, 일반적인 문제와 달리 하나의 정점에서 어느 방향을 보고 있느냐에 따라서 해당 정점의

   의미가 달라지는 문제이다. 핵심부터 말하자면, 똑같은 (1,1)에서 동쪽으로 보고있냐 남쪽을 보고있냐에 따라 다르다는

   것이다. 즉, 이미 탐색한 정점을 체크해주는 배열을 3차원 배열을 사용해줘야한다.

   Visit[x좌표][y좌표][바라보고 있는 방향] 이렇게 !

  

2) 바라보고 있는 방향을 1)에서 읽어본 방식으로 체크해주자. 또 하나는, 인접한 상하좌우로 한 칸씩 이동하는 것이 아니라

   현재 바라보고 있는 방향에서 최소 1칸에서 최대 3칸까지 한번에 움직일 수 있다는 점이 다르다.

   이 부분만 신경써서 구현해준다면 일반적인 BFS/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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include<iostream>
#include<vector>
#include<queue>
 
#define endl "\n"
#define MAX 101
using namespace std;
 
int M, N;
int MAP[MAX][MAX];
bool Visit[MAX][MAX][5];
 
int dx[] = { 0001- 1 };
int dy[] = { 01-100 };
 
vector<pair<pair<intint>int >> Start, End;
 
void Input()
{
    cin >> M >> N;
    for (int i = 1; i <= M; i++)
    {
        for (int j = 1; j <= N; j++)
        {
            cin >> MAP[i][j];
        }
    }
    int a, b, c;
    cin >> a >> b >> c;
    Start.push_back(make_pair(make_pair(a, b), c));
    cin >> a >> b >> c;
    End.push_back(make_pair(make_pair(a, b), c));
}
 
bool Can_Go(int x, int y, int d, int k)
{
    int nx = x + dx[d] * k;
    int ny = y + dy[d] * k;
 
    if (nx < 1 || ny < 1 || nx > M || ny > N) return false;
 
    nx = x;
    ny = y;
 
    for (int i = 0; i < k; i++)
    {
        nx = nx + dx[d];
        ny = ny + dy[d];
 
        if (MAP[nx][ny] == 1return false;
    }
    return true;
}
 
int Change_Direction(int d, char c)
{
    if (c == 'L')
    {
        if (d == 1return 4;
        else if (d == 2return 3;
        else if (d == 3return 1;
        else if (d == 4return 2;
    }
    else if (c == 'R')
    {
        if (d == 1return 3;
        else if (d == 2return 4;
        else if (d == 3return 2;
        else if (d == 4return 1;
    }
}
 
void BFS(int a, int b, int c)
{
    queue < pair<pair<intint>pair<intint>>> Q;
    Q.push(make_pair(make_pair(a, b), make_pair(c, 0)));
    Visit[a][b][c] = true;
 
    while (Q.empty() == 0)
    {
        int x = Q.front().first.first;
        int y = Q.front().first.second;
        int d = Q.front().second.first;
        int Cnt = Q.front().second.second;
        Q.pop();
 
        if (x == End.front().first.first && y == End.front().first.second && d == End.front().second)
        {
            cout << Cnt << endl;
            return;
        }
 
        for (int i = 1; i <= 3; i++)
        {
            if (Can_Go(x, y, d, i) == true)
            {
                int nx = x + dx[d] * i;
                int ny = y + dy[d] * i;
 
                if (Visit[nx][ny][d] == false)
                {
                    Visit[nx][ny][d] = true;
                    Q.push(make_pair(make_pair(nx, ny), make_pair(d, Cnt + 1)));
                }
            }
        }
 
        int nd;
        nd = Change_Direction(d, 'L');
        if (Visit[x][y][nd] == false)
        {
            Visit[x][y][nd] = true;
            Q.push(make_pair(make_pair(x, y), make_pair(nd, Cnt + 1)));
        }
 
        nd = Change_Direction(d, 'R');
        if (Visit[x][y][nd] == false)
        {
            Visit[x][y][nd] = true;
            Q.push(make_pair(make_pair(x, y), make_pair(nd, Cnt + 1)));
        }
    }
}
 
void Solution()
{
    int x = Start.front().first.first;
    int y = Start.front().first.second;
    int d = Start.front().second;
    BFS(x, y, d);
}
 
void Solve()
{
    Input();
    Solution();
}
 
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    //freopen("Input.txt", "r", stdin);
    Solve();
 
    return 0;
}
cs


+ Recent posts