처음에 괜히 이것저것 최소화 시키면서 풀려다보니 굉장히 힘들었다.
그치만 맵 크기가 10x10이므로 모든 경우에 대해 탐색해도 실행시간이 얼마 나오지 않는다!
풀이법은 SWExpert의 요리사, 백준의 스타트 링크 문제와 굉장히 비슷하게 풀었다.
1. h벡터에 H 구조체로 x,y 좌표, 출구와의 거리를 저장 시킨다. (사람)
2. e벡터에 E 구조체로 계단의 x,y 좌표, 내려가는데 걸리는 시간을 저장한다. (출구)
3. 1번출구 선택한 팀/ 2번출구 선택한 팀으로 나눠 모든경우에 대해 탐색한다.
4. 결과값을 비교하여 최소값을 출력한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | #include <iostream> #include <vector> #include <algorithm> using namespace std; struct H { int x; int y; int dist1; int dist2; H(int x, int y) :x(x), y(y) {} }; struct E { int x; int y; int time; E(int x, int y, int t) :x(x), y(y), time(t) {} }; int t, n; int map[10][10]; int calc(vector<int> &v, int t) { if (v.size() == 0) return 0; //도착시간 기준으로 정렬 sort(v.begin(), v.end()); //계단 사용중인지 확인하는 배열 int use[3] = { 0, }; //현재까지 소요된 시간 int time = v[0]; while (true) { for (int i = 0; i < v.size(); i++) { //이미 계단을 내려갔다면 continue if (!v[i])continue; //도착시간 확인 if (v[i] <= time) { for (int j = 0; j < 3; j++) { //빈 계단이 있는지 확인 if (use[j] <= 0) { use[j] = t; v[i] = 0; if (i == v.size() - 1) { return time + t; } break; } } } } //1초 지난거에 대한 처리 for (int i = 0; i < 3; i++) { use[i]--; } time++; } } int getTime(int check, vector<H> &h, vector<E> &e) { vector<int> A; //1번출구 선택 vector<int> B; //2번출구 선택 for (int i = 0; i < h.size(); i++) { if (check & (1 << i)) A.push_back(h[i].dist1); else B.push_back(h[i].dist2); } return max(calc(A, e[0].time), calc(B, e[1].time)); } int main() { ios_base::sync_with_stdio(false); cin >> t; for (int tc = 1; tc <= t; tc++) { cin >> n; vector<H> h; vector<E> e; int x; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cin >> x; if (x == 1) h.push_back(H(i, j)); else if (x > 1)e.push_back(E(i, j, x)); } } //출구들과 거리 계산하기 for (int i = 0; i < h.size(); i++) { h[i].dist1 = abs(h[i].x - e[0].x) + abs(h[i].y - e[0].y); h[i].dist2 = abs(h[i].x - e[1].x) + abs(h[i].y - e[1].y); } //완전 탐색 int res = 987654321; for (int i = 0; i < (1 << h.size()); i++) { res = min(res, getTime(i, h, e)); } cout << "#" << tc << " " << res + 1 << endl; } } | cs |
'SWEA::문제풀이' 카테고리의 다른 글
2112 보호 필름 (3) | 2018.04.13 |
---|---|
4112 이상한 피라미드 탐험 (0) | 2018.04.12 |
1861 정사각형 방 (0) | 2018.04.10 |
4014 활주로 건설 (2) | 2018.04.09 |
3304 최장 공통 부분 수열 (0) | 2018.04.08 |