반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 파라메트릭
- boj #19237 #어른 상어
- msSQL
- 이분탐색
- 소프티어
- 백준
- @P0
- softeer
- 기술면접
- OFFSET
- Kafka
- Docker
- 성적평가
- 매개변수탐색
- BFS
- 퇴사통보
- upper_bound
- 경력
- 처우협의
- 13908
- 6987
- 물채우기
- dfs
- 연결요소
- BOJ
- incr
- compose
- 오퍼레터
- 처우산정
- 백트래킹
Archives
- Today
- Total
기술 블로그
2383번 점심 식사시간 본문
728x90
반응형
엄청 어려운 문제였다.(내가 못 하는건 비밀)
아마 며칠 동안 풀어도 못 풀었을 것이다.
어쩔 수 없이 강의들으면서 코드를 작성하였다.
이 문제를 통해 기억해야할 것
1. 문제를 풀기 전에 설계를 잘 하자.
2. 배열을 잘 활용하자
https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5-BEE6AK0DFAVl
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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | #include <iostream> #include <queue> #include <cstdio> #include <vector> #include <cstring> #include <string> #include <math.h> #include <algorithm> #define Max_people 11 #define Max_time Max_people * 2 + Max_people*Max_people // Max_time : 최대 도착 시간 = 최대 도착 시간인 Max_people * 2 + 길이가 Max_people인 하나의 계단을 // Max_people명이 모두 다 내려갈 때 using namespace std; int N = 0; int people_count = 0; int stair_count = 0; int match[Max_people] = { 0, }; // match[h]=s : h번 째 사람이 s번 째 계단을 이용(h>=1) int ans = 987654321; int building[Max_people][Max_people] = { 0, }; vector<pair<int, int> > people[Max_people]; vector<pair<int, int> > stair[2]; // 계단은 무조건 2개 void init() // 초기화 { ans = 987654321; people_count = 0; stair_count = 0; for (int p = 0; p < 11; p++) { if (!people[p].empty()) people[p].clear(); } for (int s = 0; s < 2; s++) { if (!stair[s].empty()) stair[s].clear(); } } int dist(int human_index, int stair_index) { int dy = abs(people[human_index].front().first - stair[stair_index].front().first); int dx = abs(people[human_index].front().second - stair[stair_index].front().second); return dy + dx; } void update() { int total_time = 0; // 두 계단은 각각 독립적(서로 영향 X) for (int stair_index = 0; stair_index < 2; stair_index++) { int arrive_time[Max_people * 2] = { 0, }; // arrive_time[time] : 시간이 time일 때, 계단에 도착한 사람의 수 // 최대 걸리는 시간은 (1, 1)에서 (N, N)으로 올 때 이다. 즉, 2N이다. int current_stair[Max_time] = { 0, }; // current_stair[time] : 시간이 time일 때, 그 계단을 내려가고 있는 사람의 수 for (int human_index = 0; human_index < people_count; human_index++) { if (match[human_index] == stair_index) { arrive_time[dist(human_index, stair_index) + 1]++; // + 1을 해준 이유는 어차피 계단을 도착하고 나서, 1분 후에 계단을 내려갈 수 있기 때문이다. } } // stair_index번 째 계단을 내려가는 사람이 모두 작업을 마치기 위해 필요한 최소 시간 int now_min_time = 0; // 계단에 도착한 시간(time)을 기준으로 순차적으로 오름차순으로 각 사람이 계단을 내려가는 시뮬레이션 // 최대 도착 시간이 20인 이유는 배열을 선언할 때, 최대 11이므로, 실제 계산은 (0, 0)을 계산하는 것이 아닌 // (1, 1) ~ (11, 11)이기 때문에 |11-1| + |11-1| = 20이다. for (int time = 1; time <= 20; time++) { // 그 시간(=time)일 때, 계단에 도착하는 사람이 존재한다면 while (arrive_time[time]--) { // 해당 계단을 내려가는데 필요한 시간(=그 해당 계단의 길이) int remain_time = building[stair[stair_index].front().first][stair[stair_index].front().second]; for (int walk_time = time; walk_time < Max_time; walk_time++) { // 햔재 walk_time(time)시간일 때, 계단을 내려가는 사람 수가 3명보다 적으면 if (current_stair[walk_time] < 3) { current_stair[walk_time]++; // 1명이 내려가고 있다는 것을 추가 --remain_time; // 그에 따라 계단을 1 내려갔으므로, 1 감소 if (remain_time == 0) // 계단을 내려갔다면 { now_min_time = max(now_min_time, walk_time + 1); // + 1을 해준 이유는 // 예를 들어, 계단 길이가 3이고, time이 5일 때, 현재 그 시간에 계단을 내려가는 사람 수가 3명보다 적을 때 // if문이 실행되고, 그 5분일 때 바로 remain_time이 1 감소한다.(remain_time = 2) // 6분일 때, remain_time = 1 // 7분일 때, remain_time = 0 // remain_time이 0일 때, 바로 도착했다는 if문이 실행된다. // 근데 +1을 안 해주면 그 시간대(time = 7)로 기록해버린다. // 그래서 +1을 해주어야 '계단 길이 = 내려간 시간'임을 활용할 수 있다. break; } } } } // 전체 계단을 내려가는데 필요한 최소의 시간 = // 두 계단을 내려가는데 필요한 최소의 시간 중에서 최댓값 total_time = max(total_time, now_min_time); } } ans = min(ans, total_time); } void DFS(int human_index) // BackTracking { if (human_index == people_count) // 결정했다면 { update(); return; } for (int stair_index = 0; stair_index < 2; stair_index++) { match[human_index] = stair_index; // 사람이 어느 계단을 탈지 결정 //printf("%d번 째 사람이 %d번 째 계단 타는 경우의 수\n\n", human_index, stair_index); DFS(human_index + 1); } } int main(void) { int T = 0; scanf("%d", &T); for (int tc = 1; tc <= T; tc++) { init(); scanf("%d", &N); for (int i = 1; i <= N; i++) { for (int j = 1; j <= N; j++) { scanf("%d", &building[i][j]); if (building[i][j] == 1) { people[people_count++].push_back({ i,j }); } else if (building[i][j] >= 2) { stair[stair_count++].push_back({ i,j }); } } } DFS(0); printf("#%d %d\n", tc, ans); } return 0; } | cs |
728x90
반응형
'알고리즘 문제 > SW Expert Academy' 카테고리의 다른 글
2382번 미생물 격리 (0) | 2018.08.29 |
---|---|
1952번 수영장 (0) | 2018.08.27 |
1953번 탈주범 검거 (0) | 2018.08.25 |
1267번 작업순서 (0) | 2018.08.25 |
4013번 특이한 자석 (0) | 2018.08.24 |