코딩테스트/C++
[백준 BOJ] 15686번 - 치킨 배달 (C++)
최-코드
2023. 12. 16. 22:24
15686번: 치킨 배달
크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸
www.acmicpc.net
먼저 떠오른 생각은 'M의 수보다 치킨 집의 수가 더 많았을 때의 경우 어떻게 할 것인가'였다. M보다 치킨 집이 많으면 M의 개수가 되도록 추출을 해야하는데 이때 순서는 필요없으므로 조합을 사용해야겠다라고 생각했다. 이후 치킨 거리를 계산할 때 미리 치킨 집과 일반 집의 좌표를 vector<pair<int,int>> 타입으로 저장해놓고 뽑은 치킨 집에 대해서 계산해주면 편할 거 같다고 생각했다.
조합의 경우 백트래킹을 이용했고 조합이 어렵게 느껴지면 그냥 같은 수 없이 크기 순으로 이루어진 수열이라고 생각하면 될 거 같다.
#include <iostream>
#include <vector>
#include <cmath>
#define pii pair<int,int>
using namespace std;
int N,M;
vector<pii> home;
vector<pii> chi;
vector<int> combi;
int chi_count = -1;
int mindist = 987654321;
vector<int> result(100,-1);
int visit[13];
void cal()
{
//for(int i = 0 ;i<M;i++)
// cout<<combi[i]<<" ";
//cout<<endl;
for(int i = 0; i<home.size(); i++)
result[i]=987654321;
for(int i =0; i<home.size(); i++)
{
for(int j = 0; j<combi.size(); j++)
{
int tmp=abs(home[i].first-chi[combi[j]].first)+abs(home[i].second-chi[combi[j]].second);
if(result[i]>tmp)
result[i]=tmp;
}
}
int sum = 0;
for(int i = 0; i<home.size();i++)
{
sum+=result[i];
}
if(sum<mindist)
mindist=sum;
}
void dfs(int lev)
{
if(combi.size()==M)
{
cal();
return;
}
for(int i = lev; i<=chi_count; i++)
{
combi.push_back(i);
dfs(i+1);
combi.pop_back();
}
}
int main()
{
cin>>N>>M;
int get;
for(int i = 0; i<N; i++)
{
for(int j = 0; j<N; j++)
{
cin>>get;
if(get==1)
home.emplace_back(i,j);
else if(get==2)
{
chi.emplace_back(i,j);
chi_count++;
}
}
}
dfs(0);
cout<<mindist<<endl;
return 0;
}