15686번: 치킨 배달
크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸
www.acmicpc.net
생각보다 쉽게 풀었다. 치킨집이 총 13개까지 주어지는 조건을 봤고,
치킨집과 집을 매칭 시키는 것이 combination을 떠올리게 한다.
따라서 그래프 탐색이 아니라 조합, 경우의 수로 접근해봤다.
일단 보자마자 집을 원소로 가지는 a벡터, 치킨집을 원소로 가지는 b벡터를 인자로
받아 각 원소를 \(O(N^2)\)으로 순회하며 가장 작은 치킨 거리를 찾아 리턴해주는 함수를 만들었다.
1
2
3
4
5
6
7
8
9
10
11
|
int all(vector<pair<int, int>>& a, vector<pair<int, int>>& b) {
int ret = 0;
for (auto i : a) {
int tmp = 1e9;
for (auto j : b) {
tmp = min(tmp, abs(i.first - j.first) + abs(i.second - j.second));
}
ret += tmp;
}
return ret;
}
|
cs |
이건 쉽게 구현 가능하고 이제 치킨집에서 총 M개의 원소를 뽑아서 각각 a, b를 매칭 시켜주면 된다.
처음에는 next_permutation을 이용한 순열로 접근했지만 모든 경우의 수를 따지면 시간초과가 난다.
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
|
int main() {
ios::sync_with_stdio(false); cin.tie(0);
int n, m, ans = 1e9;
vector<pair<int, int>> a, b;
cin >> n >> m;
for (int i=0;i<n;++i)
for (int j = 0; j < n; ++j) {
int x; cin >> x;
if (x == 1) a.push_back({ i,j });
else if (x == 2) b.push_back({ i,j });
}
do {
vector<pair<int, int>> go;
for (int i = 0; i < m; ++i)
go.push_back(b[i]);
ans = min(ans, all(a, go));
} while (next_permutation(b.begin(), b.end()));
cout << ans << endl;
return 0;
}
|
cs |
그래서 지우고 조합으로 다시 접근해줬는데 n과m 문제를 풀어봤다면 쉽게 구현 가능하다.
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
|
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int n, m, ans = 1e9;
vector<pair<int, int>> a, b, tmp(13);
bool vis[13];
int all(vector<pair<int, int>>& a, vector<pair<int, int>>& b) {
int ret = 0;
for (auto i : a) {
int tmp = 1e9;
for (auto j : b) {
tmp = min(tmp, abs(i.first - j.first) + abs(i.second - j.second));
}
ret += tmp;
}
return ret;
}
void dfs(int cnt, int idx) {
if (cnt == m) {
vector<pair<int, int>> go;
for (int i = 0; i < m; ++i) go.push_back(tmp[i]);
ans = min(ans, all(a, go));
return;
}
for (int i = idx; i < b.size(); ++i) {
if (!vis[i]) {
vis[i] = true;
tmp[cnt] = b[i];
dfs(cnt + 1, i);
vis[i] = false;
}
}
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n >> m;
for (int i=0;i<n;++i)
for (int j = 0; j < n; ++j) {
int x; cin >> x;
if (x == 1) a.push_back({ i,j });
else if (x == 2) b.push_back({ i,j });
}
dfs(0, 0);
cout << ans << endl;
return 0;
}
|
cs |
'BOJ' 카테고리의 다른 글
BOJ 13549 숨바꼭질 3 (0) | 2020.12.28 |
---|---|
BOJ 12851 숨바꼭질 2 (0) | 2020.12.28 |
BOJ 3190 뱀 (0) | 2020.12.19 |
BOJ 1446 지름길 (0) | 2020.12.16 |
BOJ 1915 가장 큰 정사각형 (0) | 2020.12.13 |