본문 바로가기
Programming/Algorithm

swe 2382 미생물 격리

by OKOK 2018. 4. 13.

- 시뮬레이션

- 미생물이 겹쳤을 떄 어떻게 할 것인가

- 겹쳤을 때 가장 큰 방향을 찾고, 그 방향으로 모두 전환

- 전환 후, 같은 위치의 미생물 숫자를 한곳에 몰아주기.

- 가지치기 미생물이 0 이면 다른 연산 하지 않고 넘기기.


- 다른 사람 코드 참고하니, map 을 만들되, 벡터형식으로 만들어서 사용합니다.

이것 좋은 아이디어같습니다.  


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
/*
0923 미생물 격리 풀이 시작합니다.
1027 클리어
시뮬레이션,
큐에 넣음?
큐아니면 배열에 넣고,
같은 위치에 있는지 확인해봅니다.
그다음에 같은 위치에 있는 것들 중에 가장 큰 숫자의 방향을 찾아냅니다.
그리고 나머지는 흡수를 하고 이동하도록 합니다.
큐stl이 아닌 배열로 하도록 해서, 안의 인덱스 사용이 자유롭게 하도록하겠습니다.
합쳐진 것들은 0으로 되도록 하면 됩니다.
큐배열이 아니라 배열이네요.
*/
 
#include <iostream>
#include <algorithm>
using namespace std;
#define SIZE 1005//1005
int N, K, M;
struct point {
    int x, y, num, dir;
};
point micro[SIZE];
int x, y, nx, ny;
int dx[] = { 0,-1,1,0,0 };
int dy[] = { 0,0,0,-1,1 };
int maxVal;
int ans;
int hour;
 
void problemIn() {
    cin >> N >> M >> K;
    for (int i = 0; i < K; i++) {
        cin >> micro[i].x >> micro[i].y >> micro[i].num >> micro[i].dir;
    }
}
 
void init() {
    hour = 0;
    ans = 0;
}
 
/*
1. 약품에 들어가는 경우, 방향전환과 갯수 반띵
2. 위치가 겹치는 경우, 각 방향의 갯수 확인후, 가장 많은 미생물의 방향을 따르고, 갯수는 총합
- 약품에서 위치가 겹치는 경우는 없음.
1  2  3  4
상 하 좌 우
*/
int turn_back(int dir) {
    if (dir == 1return 2;
    else if (dir == 2return 1;
    else if (dir == 3return 4;
    else if (dir == 4return 3;
}
 
void solve() {
 
    while (1) {
 
        hour++;
 
        // 종료 조건
        if (hour == (M + 1)) {
            for (int i = 0; i < K; i++) {
                ans += micro[i].num;
            }
            return;
        }
 
        // 한시간 뒤로 이동 시키기.
        for (int i = 0; i < K; i++) {
            if (micro[i].num == 0continue;
            x = micro[i].x;
            y = micro[i].y;
            nx = x + dx[micro[i].dir];
            ny = y + dy[micro[i].dir];
 
            if (nx == 0 || nx == (N - 1|| ny == 0 || ny == (N - 1)) {
                micro[i].x = nx;
                micro[i].y = ny;
                micro[i].dir = turn_back(micro[i].dir);
                micro[i].num /= 2;
            }
            else {
                micro[i].x = nx;
                micro[i].y = ny;
            }
        }
 
        // 갈길을 가두고, 겹치는 미생물을 확인합니다.
        for (int i = 0; i < K; i++) {
            if (micro[i].num == 0continue;
            x = micro[i].x;
            y = micro[i].y;
            maxVal = micro[i].num;
 
 
            // 겹치는 것들 중에 미생물이 가장 큰 것을 찾음.
            // 방향 전환하기
            for (int j = 0; j < K; j++) {
                if (x == micro[j].x && y == micro[j].y) {
                    if (micro[i].num > micro[j].num) {
                        micro[j].dir = micro[i].dir;
                    }
                    else {
                        micro[i].dir = micro[j].dir;
                    }
                }
            }
        }
 
        // 합하기.
        for (int i = 0; i < (K - 1); i++) {
            if (micro[i].num == 0continue;
            for (int j = i + 1; j < K; j++) {
                if (micro[i].x == micro[j].x && micro[i].y == micro[j].y) {
                    micro[i].num += micro[j].num;
                    micro[j].num = 0;
                }
            }
        }
    }
}
 
int main() {
    int T;
    cin >> T;
    for (int tc = 1; tc <= T; tc++) {
        problemIn();
        solve();
        cout << "#" << tc << " " << ans << endl;
        init();
    }
    return 0;
}
cs