1 분 소요

Intro

image

image

문제해결 및 소스코드

NxN 크기의 Map에 빈칸(0), 집(1), 치킨집(2)의 정보가 주어진다.

구하고자하는것은 모든 치킨집들 중 M개를 선택한 뒤, 모든 각 집에 대해서 최소 치킨거리를 구하여 더해주는것이다.

따라서 다음과 같은 작업이 필요하다.

  • 모든 치킨집들 중 M개를 선택하는 방법
    • 치킨집의 순서는 상관없다 -> (A,B)를 선택하는것과 (B,A)를 선택하는것은 같은 결과.
    • 치킨집을 중복 선택할수없다 -> (A,A)와 같이 같은 치킨집을 여러번 선택 불가.
    • 따라서 “조합” 을 이용한다.
  • 각 집에 대해서 최소 치킨거리 구하기
    • 집 위치만을 저장할 변수가 필요.
    • 해당 집 기준으로 선택된 M개의 치킨집에 대해 거리 계산. ex. 집(1,2) 치킨집(4,3) -> 1-4 + 2-3 = 4
    • 최소 치킨거리만 기억하여 최종 치킨거리 도출


#include <iostream>
#include <algorithm>
#include <vector>
#include <climits>

using namespace std;

int N, M, ans = INT_MAX;
int map[50][50];
bool selected[13];		// 중복검사용 (치킨집은 최대 13개)

vector<pair<int, int>> house, chicken, temp;

int Distance()
{
	int sum = 0;

	// 각 집에 대해서
	for (int i = 0;i < house.size();i++)
	{
		int houseX = house[i].first;		// 집의 x좌표
		int houseY = house[i].second;		// 집의 y좌표
		int dist = INT_MAX;					// 임의 치킨거리

		// 선택된 치킨집들에 대해서
		for (int j = 0;j < temp.size();j++)
		{
			int chickenX = temp[j].first;	// 치킨집 x좌표
			int chickenY = temp[j].second;  // 치킨집 y좌표
			int d = abs(houseX - chickenX) + abs(houseY - chickenY);	// 치킨거리계산

			// 최소 치킨거리
			dist = min(dist, d);
		}
		// 최소 치킨거리의 합
		sum += dist;
	}
	return sum;
}

// M개의 치킨집 고르기(조합)
void Select_Chicken(int depth, int cnt)
{
	// M개를 모두 골랐을 때
	if (cnt == M)
	{
		ans = min(ans, Distance());
		return;
	}

	for (int i = depth;i < chicken.size();i++)
	{
		// 이미 고른 치킨집일 경우
		if (selected[i] == true) continue;
		selected[i] = true;

		// 고른 치킨집은 temp에 저장
		temp.push_back(chicken[i]);

		// 다음 치킨집 고르기
		Select_Chicken(i + 1, cnt + 1);
		selected[i] = false;

		// 선택 취소
		temp.pop_back();
	}
}
int main(void)
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> N >> M;

	// 입력
	for (int i = 0;i < N;i++)
	{
		for (int j = 0;j < N;j++)
		{
			cin >> map[i][j];

			// 집 위치 저장
			if (map[i][j] == 1) house.push_back(make_pair(i, j));
			// 치킨집 위치 저장
			if (map[i][j] == 2) chicken.push_back(make_pair(i, j));
		}
	}

	Select_Chicken(0, 0);
	cout << ans;

	return 0;
}

댓글남기기