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 | #include <stdio.h> #include <queue> #include <vector> #include <string.h> using namespace std; int width, total_time, num_micro; int sum_bug[105][105]; // 비교 연산자 - pq 용 class cmp { public: bool operator()(pair<pair<int, int>, pair<int, int> > a, pair<pair<int, int>, pair<int, int> > b) { if (a.second.first > b.second.first) return true; else return false; } }; // 비교연산자 - tmp_pq 용 class cmp2 { public: bool operator()(pair<pair<int, int>, pair<int, int> > a, pair<pair<int, int>, pair<int, int> > b) { if (a.second.first < b.second.first) return true; else return false; } }; priority_queue<pair<pair<int,int>, pair<int,int> >, vector<pair<pair<int, int>, pair<int, int> > >, cmp > pq; // (y,x),(num_bug,dir) priority_queue<pair<pair<int, int>, pair<int, int> >, vector<pair<pair<int, int>, pair<int, int> > >, cmp2 > tmp_pq; // (y,x),(num_bug,dir) // 함수들 void initialize(); void time_after(); void print_total(int time) { int rst_bug = 0; while (!pq.empty()) { int y = pq.top().first.first; int x = pq.top().first.second; rst_bug += sum_bug[y][x]; pq.pop(); } printf("#%d %d\n", time, rst_bug); } int main() { int test; scanf("%d", &test); for (int t = 1; t <= test; t++) { initialize(); for (int i = 0; i < total_time; i++) time_after(); print_total(t); } } void time_after() { while (!tmp_pq.empty()) tmp_pq.pop(); while (!pq.empty()) { // 맨 위의 원소 확인 - 추출 int y = pq.top().first.first; int x = pq.top().first.second; int num_bug = sum_bug[y][x]; int cur_dir = pq.top().second.second; pq.pop(); // sum_bug 초기화 sum_bug[y][x] = 0; // 방향 확인 후 이동 int next_x = x, next_y = y; if (cur_dir == 1) next_y -= 1; if (cur_dir == 2) next_y += 1; if (cur_dir == 3) next_x -= 1; if (cur_dir == 4) next_x += 1; // 경계선일 경우 if (next_x == 0 || next_x == width - 1 || next_y == 0 || next_y == width - 1) { // 절반으로 벌레가 줄어들며 num_bug /= 2; // 방향이 반대로 된다 if (cur_dir == 1) cur_dir = 2; else if (cur_dir == 2) cur_dir = 1; else if (cur_dir == 3) cur_dir = 4; else if (cur_dir == 4) cur_dir = 3; } // tmp_pq 에 집어넣기 if(num_bug > 0) tmp_pq.push(make_pair(make_pair(next_y, next_x), make_pair(num_bug, cur_dir))); } // flag 배열 생성 - 겹치게 되는 경우 방지 int flag[105][105] = { 0 }; // tmp_pq 를 pq 에 집어넣기 + sum_bug 초기화 while (!tmp_pq.empty()) { // 맨 위의 원소 확인 - 추출 int y = tmp_pq.top().first.first; int x = tmp_pq.top().first.second; int num_bug = tmp_pq.top().second.first; int cur_dir = tmp_pq.top().second.second; tmp_pq.pop(); // sum_bug 초기화 sum_bug[y][x] += num_bug; // flag 확인하기 - 비어있을 경우에만 다음 큐로 넘긴다 if (flag[y][x] == 0) { // pq 에 집어넣기 pq.push(make_pair(make_pair(y, x), make_pair(num_bug, cur_dir))); flag[y][x] = 1; } } } void initialize() { // memset memset(sum_bug, 0, sizeof(sum_bug)); // scanf scanf("%d %d %d", &width, &total_time, &num_micro); // pq clear while (!pq.empty()) pq.pop(); // micro 각각 for (int i = 1; i <= num_micro; i++) { int y, x, num_bug, cur_dir; scanf("%d %d %d %d", &y, &x, &num_bug, &cur_dir); pq.push(make_pair(make_pair(y, x), make_pair(num_bug, cur_dir))); sum_bug[y][x] = num_bug; } } | cs |
어후...
이틀이나 걸렸다
물론 이틀 내내 한건 아니지만..
정신적으로 좀 힘들었다
푸는데만 6시간 걸린거같은데..
두 개의 우선순위 큐를 활용해서 풀어내는 문제였다
앞으로 시간 초과가 염려될 때는,
초장부터 배열이 아닌 큐나 다른 효율적인 자료구조를 사용해야겠다
웬지 앞에서도 시간초과로 못 풀었던 문제도 우선순위 큐로 해결 가능할거같다..
힘들다..
'삼성 코팅테스트 준비 > 모의 역량 테스트 문제' 카테고리의 다른 글
1949 등산로 조성 (0) | 2020.03.07 |
---|---|
해결) 5653 줄기세포 배양 (0) | 2020.03.07 |
2117 홈 방범 서비스 (0) | 2020.03.05 |
4014 활주로 건설 (0) | 2020.03.04 |
1953 탈주범 검거 (0) | 2020.03.04 |