기술 블로그

5653번 줄기세포 배양 본문

알고리즘 문제/SW Expert Academy

5653번 줄기세포 배양

parkit 2018. 10. 5. 21:52
728x90
반응형

어려웠다.


SWEA의 미생물 격리 문제처럼 풀려고 하였으나, 방법이 안 떠올랐다.


그래서, 다른 분의 코드를 보았는데 queue를 활용하는 것이 중요하였다.


나는 queue를 '배열'로 활용한다는 것을 이 문제에서는 생각하지도 못 했다.


더 열심히 해야겠다.



추가적으로, cell 구조체 안에 occupy 때문에 조금 고생하였다.


61번 째 줄 코드에 p가 0일 경우도 occupy에 true가 들어가버리기 때문에,


105번 째 줄 if문을 무시하게 된다. 


그래서, 65번 째 줄처럼 continue를 사용해 p가 0일 경우를 무시해줘야한다.


또한, 굳이 occupy를 쓸 필요가 없었다.


세포는 무조건 생명력 수치가 1 이상이기 때문이다. 


occupy를 안 쓰는 코드는, 두 번째 코드이다.



https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRJ8EKe48DFAUo



occupy를 쓸 경우

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
#include <iostream>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <math.h>
#include <algorithm>
#include <map>
 
using namespace std;
 
typedef struct cell
{
    int Power;
    int time;
    bool occupy;
}cell;
 
int dy[4= { -1010 };
int dx[4= { 0-101 };
 
int N = 0, M = 0;
 
int K = 0;
 
cell Cell[600][600];
 
void init()
{
    for (int i = 0; i < 600; i++)
    {
        for (int j = 0; j < 600; j++)
        {
            Cell[i][j].occupy = false;
            Cell[i][j].Power = 0;
            Cell[i][j].time = 0;
        }
    }
}
 
int main(void)
{
    int T = 0, p = 0;
 
    scanf("%d"&T);
 
    for (int tc = 1; tc <= T; tc++)
    {
        init();
 
        scanf("%d %d %d"&N, &M, &K);
 
        queue<pair<intint> > q[11];
 
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < M; j++)
            {
                int p = 0;
 
                scanf("%d"&p);
 
                if (p == 0continue;
 
                Cell[300 + i][300 + j].Power = p;
                Cell[300 + i][300 + j].time = 2 * p;
                Cell[300 + i][300 + j].occupy = true;
 
                if (p != 0)
                {
                    q[p].push({ 300 + i, 300 + j });
                }
            }
        }
 
        while (K--)
        {
            // 생명력 수치가 높은 순서
            for (int i = 10; i >= 1; i--)
            {
                int qSize = q[i].size();
 
                for (int j = 0; j < qSize; j++)
                {
                    int r = q[i].front().first;
                    int c = q[i].front().second;
 
                    q[i].pop();
 
                    --Cell[r][c].time;
                    
                    if (Cell[r][c].Power > Cell[r][c].time)
                    {
                        // 남은 시간이 항상 작더라도 어차피 occupy에 의해 증식이 한 번 되었더라면, 그 이후
                        // 바로 아래 for문이 실행되어도 상관 없음.
 
                        // 활성화가 되었다면
                        for (int k = 0; k < 4; k++)
                        {
                            int y = r + dy[k];
                            int x = c + dx[k];
 
                            if (!Cell[y][x].occupy)
                            {
                                Cell[y][x].occupy = true;
                                Cell[y][x].Power = Cell[r][c].Power;
                                Cell[y][x].time = 2 * Cell[r][c].Power;
 
                                q[i].push({ y,x });
                            }
                        }
                    }
 
                    // 아직 안 죽었다면(활성)
                    if (Cell[r][c].time != 0)
                    {
                        q[i].push({ r, c });
                    }
                }
            }
        }
 
        int result = 0;
        
        for (int i = 1; i <= 10; i++)
        {
            result += q[i].size();
        }
 
        printf("#%d %d\n", tc, result);
    }
    
    return 0;
}
cs





occupy를 쓸 경우
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
#include <iostream>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <math.h>
#include <algorithm>
#include <map>
 
using namespace std;
 
typedef struct cell
{
    int Power;
    int time;
}cell;
 
int dy[4= { -1010 };
int dx[4= { 0-101 };
 
int N = 0, M = 0;
 
int K = 0;
 
cell Cell[600][600];
 
void init()
{
    for (int i = 0; i < 600; i++)
    {
        for (int j = 0; j < 600; j++)
        {
            Cell[i][j].Power = 0;
            Cell[i][j].time = 0;
        }
    }
}
 
int main(void)
{
    int T = 0, p = 0;
 
    scanf("%d"&T);
 
    for (int tc = 1; tc <= T; tc++)
    {
        init();
 
        //scanf("%d %d %d", &N, &M, &K);
 
        cin >> N >> M >> K;
 
        queue<pair<intint> > q[11];
 
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < M; j++)
            {
                int p = 0;
 
                cin >> p;
 
                Cell[300 + i][300 + j].Power = p;
                Cell[300 + i][300 + j].time = 2 * p;
 
                if (p != 0)
                {
                    q[p].push({ 300 + i, 300 + j });
                }
            }
        }
 
        while (K--)
        {
            // 생명력 수치가 높은 순서
            for (int i = 10; i >= 1; i--)
            {
                int qSize = q[i].size();
 
                for (int j = 0; j < qSize; j++)
                {
                    int r = q[i].front().first;
                    int c = q[i].front().second;
 
                    q[i].pop();
 
                    --Cell[r][c].time;
 
                    if (Cell[r][c].Power > Cell[r][c].time)
                    {
                        // 남은 시간이 항상 작더라도 어차피 occupy에 의해 증식이 한 번 되었더라면, 그 이후
                        // 바로 아래 for문이 실행되어도 상관 없음.
 
                        // 활성화가 되었다면
                        for (int k = 0; k < 4; k++)
                        {
                            int y = r + dy[k];
                            int x = c + dx[k];
 
                            if (Cell[y][x].Power == 0)
                            {
                                Cell[y][x].Power = Cell[r][c].Power;
                                Cell[y][x].time = 2 * Cell[r][c].Power;
 
                                q[i].push({ y,x });
                            }
                        }
                    }
 
                    // 아직 안 죽었다면(활성)
                    if (Cell[r][c].time != 0)
                    {
                        q[i].push({ r, c });
                    }
                }
            }
        }
 
        int result = 0;
 
        for (int i = 1; i <= 10; i++)
        {
            result += q[i].size();
        }
 
        printf("#%d %d\n", tc, result);
    }
 
    return 0;
}
cs


728x90
반응형

'알고리즘 문제 > SW Expert Academy' 카테고리의 다른 글

홈 방범 서비스  (0) 2019.05.24
1767번 프로세서 연결하기  (0) 2019.04.14
2477번 차량 정비소  (0) 2018.09.14
2117번 홈 방범 서비스  (0) 2018.09.01
2105번 디저트 카페  (0) 2018.08.31