https://www.acmicpc.net/problem/15686
15686번: 치킨 배달
크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸, 왼쪽에서부터 c번째 칸을 의미한다. r과 c는 1부터 시작한다. 이 도시에 사는 사람들은 치킨을 매우 좋아한다. 따라서, 사람들은 "치킨 거리"라는 말을 주로 사용한다. 치킨 거리는 집과 가장 가까운 치킨집 사이의 거리이다. 즉, 치킨 거리는
www.acmicpc.net
[문제 풀이]
조합을 이용하여 문제를 풀었습니다.
도시의 치킨집 중에 M개를 조합을 이용하여 골라줍니다. M개의 치킨집이 선택되었다면 치킨 거리의 최솟값을 구해 주었습니다. 그 후 최솟값이 도시의 가장 작은 치킨 거리인가를 확인해 주었습니다.
[코드]
#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
int map[51][51];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
vector<pair<int, int>> store;
vector<pair<int, int>> home;
int home_distance[250] = { 987654321, };
int check[13] = { 0, };
int N, M;
int result = 987654321;
void select(int, int);
void cal();
int main() {
scanf("%d %d", &N, &M);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
scanf("%d", &map[i][j]);
if (map[i][j] == 1) {
home.push_back(make_pair(i, j));
}
if (map[i][j] == 2)
store.push_back(make_pair(i, j));
}
}
for (int i = 0; i < store.size(); i++) {
check[i] = 1;
select(i, 1);
check[i] = 0;
}
printf("%d\n", result);
}
void cal() {
int sum = 0;
for (int i = 0; i < home.size(); i++)
home_distance[i] = 987654321;
for (int i = 0; i < 13; i++) {
if (check[i] == 1) {
for (int j = 0; j < home.size(); j++) {
int distance = abs(home[j].first - store[i].first) + abs(home[j].second - store[i].second);
if (home_distance[j] > distance)
home_distance[j] = distance;
}
}
}
for (int i = 0; i < home.size(); i++)
sum += home_distance[i];
if (sum < result)
result = sum;
}
void select(int idx, int cnt) {
if (cnt == M) {
cal();
return;
}
if (idx + 1 == store.size())
return;
for (int i = idx + 1; i < store.size(); i++) {
check[i] = 1;
select(i, cnt + 1);
check[i] = 0;
}
}
'algorithm > BOJ' 카테고리의 다른 글
백준 16236_아기 상어(C++) (0) | 2020.04.24 |
---|---|
백준 15684_사다리 조작(C++) (0) | 2020.04.23 |
백준 14889_스타트와 링크(C++) (0) | 2020.04.18 |
백준 14891_톱니바퀴(C++) (0) | 2020.04.17 |
백준 3190_뱀(C++) (0) | 2020.04.08 |