알고리즘 문제풀이(C++)

[BOJ15686][C++] 치킨 배달

hyowonii 2022. 3. 26. 21:10

https://www.acmicpc.net/problem/15686

 

15686번: 치킨 배달

크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸

www.acmicpc.net

문제

 

해결

🎈Key Point🎈

입력받은 치킨집 중에서 M개를 뽑기 -> 조합(백트래킹) 사용

뽑은 치킨집 중에서 다시 치킨 거리가 최소일 때를 구함

 

입력받은 치킨집 중에서 M개로 이루어진 묶음을 모두 저장한 다음 모든 묶음을 돌면서 치킨 거리를 계산하고, 그 중 최소거리를 정답으로 출력하면 된다.

 

[전체 코드]

 

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

typedef pair<int, int> pi;

int N, M;
vector<pi> house;
vector<pi> chicken;
vector<vector<pi>> selected;
int result = 1e9;

vector<pi> one_pack;
void Combination(int k) {

	if (one_pack.size() == M) {
		selected.push_back(one_pack);
	}
	else if (k == chicken.size()) {  }
	else {
		one_pack.push_back(chicken[k]);
		Combination(k + 1);
		one_pack.pop_back();
		Combination(k + 1);
	}
}

int Distance(pi h, vector<pi> pack) {
	int minDis = 1e9;
	
	for (auto p : pack) {
		int dis = abs(h.first - p.first) + abs(h.second - p.second);
		minDis = min(minDis, dis);
	}

	return minDis;
}

int main(void) {
	ios::sync_with_stdio(0);
	cin.tie(0);

	// 입력
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			int num;
			cin >> num;
			if (num == 1) house.push_back({ i, j });
			if (num == 2) chicken.push_back({ i, j });
		}
	}
	// 

	Combination(0);		// M개로 이루어진 치킨집 조합을 모두 저정한다.

	for (auto pack : selected) {
		int disSum = 0;

		for (auto h : house) {
			disSum += Distance(h, pack);	// 하나의 치킨집 조합에 대해 치킨 거리 계산
		}

		result = min(result, disSum);
	}

	cout << result;
}