본문 바로가기

짜잘한 기록

백준 15686 치킨 배달

구현 문제를 풀어보자고 해서 잡은 문제이다.

2D 지도를 입력받고,  치킨 집 중 M개를 선택해 각 집에서 가장 가까운 치킨집 거리들의 합 최소값을 구하면 되는 문제이다.

구현 문제기도 하고, 맵 크기도 50 * 50 = 2500개 셀이라 크지 않아서 전체 탐색으로 구현했다.

 

처음 맵 입력을 받을 때, 집 위치와 치킨집 위치를 각 벡터에 저장한다.

탐색하는 공간은 전체 치킨집 중에서 어떤 특정한 치킨집들을 선택하는 경우를 비트마스킹으로 탐색했다. 전체 탐색 공간의 수는 2^치킨집의 수 이다. 하지만 이 경우 중에서 선택한 치킨집의 수가(1의 수가) M개인 경우만 사용한다.

각 경우에서는 집을 순회하면서 그 집에서 가장 가까운 치킨집의 거리를 더해나간다. 가장 가까운 치킨집 거리 역시 각 치킨집을 모두 돌면서 최소값을 찾았다. 치킨집의 수도 최대 13개 이므로 다 돌아도 경우의 수가 많지 않다.

 

결국 (거의)전체 탐색을 돌면서 거리의 최소값을 찾는 문제이다. 구현하고 첫트에 맞았습니다를 띄웠다. 아싸.


#include <iostream>
#include <cstring>
#include <vector>
#include <climits>

int check_1(int i)
{
    int ret = 0;
    while (i)
    {
        ret += (i & 1);
        i = i >> 1;
    }
    return (ret);
}

int get_dist(std::pair<int, int> p1, std::pair<int, int> p2)
{
    return (std::abs(p1.first - p2.first) + std::abs(p1.second - p2.second));
}

int main()
{
    int map[51][51];
    memset(map, 0, sizeof(map));
    int N, M;
    std::vector<std::pair<int, int>> chicken;
    std::vector<std::pair<int, int>> house;
    std::cin >> N >> M;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            std::cin >> map[i][j];
            if (map[i][j] == 1)
                house.push_back(std::make_pair(i,j));
            else if (map[i][j] == 2)
                chicken.push_back(std::make_pair(i, j));
        }
    }
    
    int min_dist = INT_MAX;
    for (int i = 0; i < (1 << (chicken.size())); i++)
    {
        int dist = 0;
        if (M != check_1(i))
            continue;
        for (int j = 0; j < house.size(); j++)
        {
            int chicken_dist = INT_MAX;
            for (int k = 0; k < chicken.size(); k++)
            {
                if (i & (1 << k))
                {
                    chicken_dist = std::min(get_dist(house[j], chicken[k]), chicken_dist);
                }
            }
            dist += chicken_dist;
        }
        min_dist = std::min(min_dist, dist);
    }
    std::cout << min_dist;
}

 

구현 문제는 쉬운걸 잡으면 확 쉬워지는 느낌이다. 조금 어려운 것을 한번 풀어봐야겠다. 휴. 화이팅

 

오늘도 평온한 하루가 되길. 슨민.

'짜잘한 기록' 카테고리의 다른 글

[문을 편하게 열고 싶다] UID changable tag에 카드 복사하기(완)  (0) 2021.11.04
백준 15683 감시  (0) 2021.11.03
백준 14939 불 끄기  (0) 2021.10.27
백준 14391 종이 조각  (0) 2021.10.26
백준 9328 열쇠  (0) 2021.10.22