Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Tags
more
Archives
Today
Total
관리 메뉴

대웅짱님의 블로그

[4991] 로봇 청소기 본문

알고리즘/BOJ

[4991] 로봇 청소기

대웅짱 2018. 7. 5. 19:59

문제: https://www.acmicpc.net/problem/4991


로봇 청소기의 시작위치와 로봇 청소기가 치워야 할 쓰레기들의 위치가 주어졌을 때


로봇이 모든 쓰레기들을 치우는데 필요한 최소 움직임을 출력하는 문제이다.


BFS를 이용해 로봇 청소기와 각 쓰레기들 간의 거리를 모두 계산 후


next_permutation을 이용해 모든 수열에 대해 값을 더해보고 최솟 값을 출력해 주었다.


사실 next_permutation말고 DP를 이용해도 가능한데 쓰레기의 최대 개수가 10개 밖에 되지 않아서


그냥 완탐으로 구현했다.




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
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int arr[22][22];
int len[11][11];
bool visit[22][22];
int dx[4= { 001-1 };
int dy[4= { 1-100 };
int n, m;
int dirtysize;
 
bool isPoosible(int x, int y) {
    return x >= 0 && x < m && y >= 0 && y < n;
}
 
void bfs(int x, int y) {
    queue<pair<intint> > qu;
    int cnt = 0;
    visit[x][y] = 1;
    qu.push({ x, y });
    while (int s = (int)qu.size()) {
        while (s--) {
            int cx = qu.front().first;
            int cy = qu.front().second;
            qu.pop();
            if (arr[cx][cy] >= 0) len[arr[x][y]][arr[cx][cy]] = cnt;
            
            for (int i = 0; i < 4; i++) {
                int nx = dx[i] + cx;
                int ny = dy[i] + cy;
                if (isPoosible(nx, ny) && arr[nx][ny] != -2 && !visit[nx][ny]) {
                    visit[nx][ny] = 1;
                    qu.push({ nx, ny });
                }
            }
        }
        cnt++;
    }
}
 
int main() {
    while (scanf("%d %d"&n, &m) != EOF) {
        if (!&& !m) return 0;
        memset(arr, 0sizeof(arr));
        memset(len, 0sizeof(len));
        int cnt = 1;
        queue<pair<intint> > dirty;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j <n; j++) {
                char c;
                scanf(" %1c"&c);
                if (c == 'o') {
                    arr[i][j] = 0;
                    dirty.push({ i, j });
                }
                else if (c == '.') arr[i][j] = -1;
                else if (c == 'x') arr[i][j] = -2;
                else {
                    arr[i][j] = cnt++;
                    dirty.push({ i, j });
                }
            }
        }
 
        dirtysize = (int)dirty.size();
        for (int i = 0; i < dirtysize; i++) {
            memset(visit, 0sizeof(visit));
            int x = dirty.front().first;
            int y = dirty.front().second;
            dirty.pop();
            bfs(x, y);
        }
        
        if (dirtysize == 1) {
            puts("0");
            continue;
        }
        vector<int> vt;
        for (int i = 1; i < dirtysize; i++) vt.push_back(i);
        int mini = 987654321;
        bool flag = 0;
        do {
            int sum = len[0][vt[0]];
            if (sum == 0) flag = 1;
            for (int i = 0; i < dirtysize - 2; i++) {
                sum += len[vt[i]][vt[i + 1]];
                if (len[vt[i]][vt[i + 1]] == 0) flag = 1;
            }
            mini = min(mini, sum);
        } while (next_permutation(vt.begin(), vt.end()));
        if (flag) puts("-1");
        else printf("%d\n", mini);
    }
    return 0;
}
cs


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

[13460] 구슬 탈출 2  (0) 2019.01.29
[9328] 열쇠  (0) 2018.07.10
[5427] 불  (0) 2018.07.04
[2146] 다리 만들기  (0) 2018.07.04
[5014] 스타트링크  (0) 2018.07.03