본문 바로가기
삼성 코팅테스트 준비/모의 역량 테스트 문제

2382 미생물 격리

by tryotto 2020. 3. 6.
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<intint>pair<intint> > a, pair<pair<intint>pair<intint> > b) {
        if (a.second.first > b.second.first)
            return true;
        else
            return false;
    }
};
 
// 비교연산자 - tmp_pq 용 
class cmp2 {
public:
    bool operator()(pair<pair<intint>pair<intint> > a, pair<pair<intint>pair<intint> > 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<intint>pair<intint> > >, cmp > pq;    // (y,x),(num_bug,dir)
priority_queue<pair<pair<intint>pair<intint> >,
    vector<pair<pair<intint>pair<intint> > >, 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, 0sizeof(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