:: ADVANCE ::

[BaekJoon][1261] 알고스팟 본문

Algorithm/ES (완전탐색)

[BaekJoon][1261] 알고스팟

KSJ14 2016. 6. 9. 16:08
반응형

BAEKJOON ONLINE JUDGE


1261 알고스팟


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




입력이 0일 경우에는 벽을 부술 필요 없이 바로 이동하면 되므로 DFS이건 BFS이건 탐색을 하면 된다.

입력이 1일 경우에는 벽을 부수어야 하기 때문에 바로 이동을 하면 안된다.


단계별로 나누면

1. 바로 갈 수 있는 곳은 바로간다.

2. 더이상 갈 수 없으면 벽을 부순다.

3. 벽을 부순 후 갈 수 있는만큼 이동한다.

이걸 반복해서 마지막 장소에 도착하면 된다.


풀이 1. 

입력이 0인 곳은 DFS, 그 중 벽을 만나면 queue에 저장

DFS가 끝난 후 queue에 저장된 벽을 부순 후 다시 DFS를 타서 바로 갈 수 있는 곳은 이동

이동하면서 다시 벽을 만나면 queue에 저장


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
#include <stdio.h>
#include <queue>
using namespace std;
 
typedef struct tagData {
    int y;
    int x;
    int cnt;
}Data;
 
int map[101][101];
int inputdata[101][101];
queue<Data> que;
int n, m;
 
void init()
{
    int i, j;
 
    for (i = 0; i < 101; i++) {
        for (j = 0; j < 101; j++) {
            map[i][j] = -1;
        }
    }
}
 
void input()
{
    int i, j;
 
    scanf("%d %d", &m, &n);
 
    for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
            scanf("%1d", &inputdata[i][j]);
        }
    }
}
 
void print()
{
    int i, j;
    for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
            if (map[i][j] < 0)    printf(" ");
            else printf("%d", map[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}
 
Data makedata(int y, int x, int cnt)
{
    Data data;
    data.y = y;
    data.x = x;
    data.cnt = cnt;
    return data;
}
 
void dfs(int y, int x, int cnt) 
{
    int dx[4= { -1001 };
    int dy[4= { 0-110 };
    int nexty, nextx;
    int i;
 
    map[y][x] = cnt;
 
    for (i = 0; i < 4; i++) {
        nexty = y + dy[i];
        nextx = x + dx[i];
 
        if (nexty >= 0 && nexty < n && nextx >= 0 && nextx < m) {
            if(map[nexty][nextx] < 0 && !inputdata[nexty][nextx])        
                dfs(nexty, nextx, cnt);
            else {
                map[nexty][nextx] = cnt + 1;
                que.push(makedata(nexty, nextx, cnt + 1));
            }
        }
    }
}
 
void go()
{
    Data data;
    int dx[4= { -1001 };
    int dy[4= { 0-110 };
    int tempy, tempx;
    int flag;
    int i;
 
    dfs(000);
 
    while (map[n - 1][m - 1< 0 && !que.empty()) {
        data = que.front();
        que.pop();
 
        flag = 1;
        for (i = 0; i < 4; i++) {
            tempy = data.y + dy[i];
            tempx = data.x + dx[i];
            if (tempy >= 0 && tempy < n && tempx >= 0 && tempx < m) {
                if (map[tempy][tempx] < 0 && !inputdata[tempy][tempx]) {
                    flag = 0;
                    dfs(tempy, tempx, data.cnt);
                }
            }
        }
 
        if (flag) {
            for (i = 0; i < 4; i++) {
                tempy = data.y + dy[i];
                tempx = data.x + dx[i];
                if (tempy >= 0 && tempy < n && tempx >= 0 && tempx < m) {
                    if (map[tempy][tempx] < 0 && inputdata[tempy][tempx]) {
                        que.push(makedata(tempy, tempx, data.cnt + 1));
                    }
                }
            }
        }
    }
}
 
int main()
{
    init();
 
    input();
 
    go();
 
    printf("%d\n", map[n - 1][m - 1]);
 
    return 0;
}
 
cs



풀이 2. 

입력이 0인 지점은 바로 이동

벽을 만나면 +1을 한 후 더이상 이동하지 않는다.
이동할 수 있는곳을 다 탐색한 후

다시 map을 돌면서 마지막으로 벽을 부수었던 곳을 찾아 다시 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
#include <stdio.h>
 
int n, m;
int map[100][100];
int count[100][100];
 
void input()
{
    int i, j;
 
    scanf("%d %d", &m, &n);
 
    for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
            scanf("%1d", &map[i][j]);
        }
    }
}
 
void print()
{
    int i, j;
    for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
            printf("%d ", count[i][j]);
        }
        printf("\n");
    }
}
 
void dfs(int y, int x, int cnt)
{
    int dy[4= { -1001 };
    int dx[4= { 0-110 };
    int i;
    int nexty, nextx;
 
    if (!count[y][x]) {
        if (map[y][x]) {
            count[y][x] = cnt + 1;
            return;
        }
        count[y][x] = cnt;
    }
 
    for (i = 0; i < 4; i++) {
        nexty = y + dy[i];
        nextx = x + dx[i];
 
        if (nexty < n && nexty >= 0 && nextx < m && nextx >= 0 && !count[nexty][nextx]) {
            dfs(nexty, nextx, cnt);
        }
    }
}
 
void process()
{
    int cnt;
    int i, j;
 
    count[0][0= cnt = 1;
 
    while (count[n - 1][m - 1== 0) {
        for (i = 0; i < n; i++) {
            for (j = 0; j < m; j++) {
                if (count[i][j] == cnt) {
                    dfs(i, j, cnt);
                    if (count[n - 1][m - 1])    return;
                }
            }
        }
        cnt++;
    }
}
 
int main()
{
    input();
 
    process();
 
    printf("%d\n", count[n - 1][m - 1- 1);
 
    return 0;
}

cs


* queue를 사용한 것보다 그냥 배열을 처음부터 탐색해가는 것이 더 속도가 빨랐다.

ex) 풀이 1 : 8ms, 풀이 2 : 9ms

반응형

'Algorithm > ES (완전탐색)' 카테고리의 다른 글

[BaekJoon][2636] 치즈  (0) 2016.10.01
[BaekJoon][2146] 다리 만들기  (0) 2016.06.25
[BaekJoon][2580] 스도쿠  (0) 2016.06.05
[BaekJoon][2823] 유턴 싫어  (0) 2016.04.11
[BaekJoon][2816] 디지털 티비  (0) 2016.04.11
Comments