Programming/Algorithm
swe 2382 미생물 격리
OKOK
2018. 4. 13. 10:32
- 시뮬레이션 - 미생물이 겹쳤을 떄 어떻게 할 것인가 - 겹쳤을 때 가장 큰 방향을 찾고, 그 방향으로 모두 전환 - 전환 후, 같은 위치의 미생물 숫자를 한곳에 몰아주기. - 가지치기 미생물이 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 == 1) return 2; else if (dir == 2) return 1; else if (dir == 3) return 4; else if (dir == 4) return 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 == 0) continue; 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 == 0) continue; 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 == 0) continue; 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 |