[문제보기]
15686번: 치킨 배달
크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸
www.acmicpc.net
[풀이과정]
이 문제를 보고 완전 탐색을 사용해서 문제를 풀어야겠다고 생각했다. 재귀를 사용하여 치킨집을 M개를 골라서
집이랑의 거리를 하나씩 측정하고 값을 갱신하는 부분에서 map을 사용하여 이중 for문으로 집 위치와 치킨집 위치를
찾아 거리를 계산을 하면 시간이 많이 걸리기 때문에 처음 입력값을 받을 때 vector를 사용하여 집과 치킨집의 좌표를
저장했다.
dfs(int idx, int cnt) 함수를 진행하는데, idx변수를 입력받아 idx부터 for문을 진행해준다. 이때 check[] 라는
1차원 배열을 사용하여, 치킨집을 골랐다면 true, 없앤다면 false로 입력을 해주면서 재귀를 진행해준다.
재귀를 진행하면서 cnt는 치킨집을 몇 개 골랐는지를 의미하는 변수이므로 cnt가 n개가 되면 치킨집과 집과의
거리를 계산하는 get_dir() 함수를 진행해준다.
get_dir()은 집과 치킨집의 거리를 계산해주는 함수인데, main에서 vector로 저장해준 집과 치킨집의 좌표를 사용하여
거리를 계산해준다. 이 부분에서 집과 계산을 하는 치킨집을 고르는 부분에서 check[] 변수를 사용하여 치킨집을
골라준다.
[소스코드]
#include <iostream>
#include <vector>
#include <cstring>
#include <cmath>
using namespace std;
int n, m, del;
int ans = 987654321;
int map[51][51] = {0};
bool check[13];
vector<pair<int, int>> house;
vector<pair<int, int>> chicken;
int get_dir(){
int result = 0;
for(int i=0; i<house.size(); i++){
int sum = 987654321;
for(int j=0; j<chicken.size(); j++){
if(check[j]){
sum = min(sum, abs(house[i].first - chicken[j].first) + abs(house[i].second - chicken[j].second));
}
}
result += sum;
}
return result;
}
void dfs(int idx, int cnt){
if(cnt == m){
ans = min(ans, get_dir());
return;
}
for(int i=idx; i<chicken.size(); i++){
if(check[i] == true)
continue;
check[i] = true;
dfs(i, cnt+1);
check[i] = false;
}
}
int main(){
cin.tie(0);
cout.sync_with_stdio(false);
cin >> n >> m;
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
cin >> map[i][j];
if(map[i][j] == 1){
house.push_back({i,j});
}
else if(map[i][j] == 2){
chicken.push_back({i,j});
}
}
}
dfs(0, 0);
cout << ans ;
}
[해결과정 중 실수한 부분]
처음에는 dfs() 함수의 for문을 실행하는 부분에서 재귀로 들어갈 때마다 0부터 다시 확인하는 코드로 짰었다. 그래서
제출했을 때, 시간초과가 떠서, 이 부분을 잡기 위해서 고민을 했고, dfs() 함수에 idx를 같이 넘겨서 for문을 연산할 때
0부터가 아닌 idx부터 연산을 진행하도록 하는 것이 시간을 줄일 수 있는 방법이라는 것을 깨달았다.
시간을 잡기 위해서 1시간은 족히 고민을 했었고, 도무지 생각이 안 나서 블로그를 참고했다ㅠㅠㅠㅠㅠ.
이 부분만 잡았으면 바로 pass 할 수 있었는데ㅠㅠ
'알고리즘 스터디 > Beakjoon' 카테고리의 다른 글
| [백준 16236][C++] 아기 상어 (Gold5) (0) | 2020.08.24 |
|---|---|
| [백준 16234][C++] 인구 이동(Gold 5) (0) | 2020.08.23 |
| [백준 14888][C++] 연산자 끼워넣기 (Silver 1) (0) | 2020.08.20 |
| [백준 3190][C++] 뱀 (Gold 5) (0) | 2020.08.19 |
| [백준 14889][C++] 스타트와 링크 (Silver 3) (0) | 2020.08.18 |