반응형
https://www.acmicpc.net/problem/21611
21611번: 마법사 상어와 블리자드
마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그, 비바라기 마법을 할 수 있다. 오늘 새로 배운 마법은 블리자드이고, 크기가 N×N인 격자에서 연습하려고 한다. N은 항상 홀수이고, (
www.acmicpc.net
[ 문제풀이 ]
1. 블리자드로 구슬을 부십니다.
2. 중심에서부터 멀어지면서 vector 배열에 값이 0이 아닐 때 하나씩 푸시해줍니다.
3. 연속으로 같은 구슬이 4개 이상 있다면 터뜨려주고, 터진 구슬의 개수와 구슬의 번호를 곱해 ans에 더해줍니다.
4. 터뜨릴 구슬이 더 이상 없다면 위의 2번 방법으로 배열을 채워줍니다.
5. 채워진 vector 배열을 바탕으로 arr배열을 갱신해줍니다.
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 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | #include<iostream> #include<vector> #include<cstring> using namespace std; int N, M; int arr[51][51]; int dy[5] = { 0,-1,1,0,0 }; int dx[5] = { 0,0,0,-1,1 }; int y, x; int ans = 0; vector<int> setting(vector<int> vect) //구슬이 모두 파괴된 후 재 세팅 { vector<int> temp; int cnt = 1; if (vect.size() == 0) return vect; for (int i = 1; i < min((int)vect.size(), N * N - 1); i++) { if (vect[i] == vect[i - 1]) { cnt++; } else { temp.push_back(cnt); temp.push_back(vect[i-1]); cnt = 1; } if (temp.size() >= N * N-1) break; } temp.push_back(cnt); temp.push_back(vect[vect.size() - 1]); return temp; } vector<int> remove(vector<int> vect) //같은 구슬이 4개 이상 연속으로 있다면 파괴 { while (1) { if (vect.size() == 0) return vect; vector<int> temp; bool flag = false; int cnt = 1; for (int i = 1; i < min((int)vect.size(), N * N - 1); i++) { if (vect[i] == vect[i - 1]) { cnt++; } else { if (cnt < 4) { for (int j = 0; j < cnt; j++) { temp.push_back(vect[i - 1]); } } else { ans += vect[i - 1] * cnt; flag = true; } cnt = 1; } } if (cnt < 4) { for (int j = 0; j < cnt; j++) { temp.push_back(vect[vect.size() - 1]); } } else { ans += vect[vect.size() - 1] * cnt; flag = true; } vect = temp; if (flag == false) { break; } } return vect; } void move() //구슬 움직이기 { vector<int> vect; y = x = N / 2 + 1; int cnt = 0; for (int i = 1; i <= N; i++) { if (i % 2 == 1) { for (int j = 0; j < i; j++) { x--; if (arr[y][x] != 0) { cnt = 0; vect.push_back(arr[y][x]); } else { cnt++; } if (cnt == 2) break; } if (cnt == 2) break; for (int j = 0; j < i; j++) { y++; if (arr[y][x] != 0) { cnt = 0; vect.push_back(arr[y][x]); } else { cnt++; } if (cnt == 2) break; } if (cnt == 2) break; } else { for (int j = 0; j < i; j++) { x++; if (arr[y][x] != 0) { cnt = 0; vect.push_back(arr[y][x]); } else { cnt++; } if (cnt == 2) break; } if (cnt == 2) break; for (int j = 0; j < i; j++) { y--; if (arr[y][x] != 0) { cnt = 0; vect.push_back(arr[y][x]); } else { cnt++; } if (cnt == 2) break; } if (cnt == 2) break; } } vect = remove(vect); vect = setting(vect); memset(arr, 0, sizeof(arr)); int idx = 0; y = x = N / 2 + 1; for (int i = 1; i <= N; i++) { //세팅된 구슬 갱신 if (i % 2 == 1) { for (int j = 0; j < i; j++) { if (idx >= vect.size()) break; x--; if (x < 1) break; arr[y][x] = vect[idx]; idx++; } if (idx >= vect.size() || x < 1) break; for (int j = 0; j < i; j++) { if (idx >= vect.size()) break; y++; arr[y][x] = vect[idx]; idx++; } if (idx >= vect.size() || x < 1) break; } else { for (int j = 0; j < i; j++) { if (idx >= vect.size()) break; x++; arr[y][x] = vect[idx]; idx++; } if (idx >= vect.size() || x < 1) break; for (int j = 0; j < i; j++) { if (idx >= vect.size()) break; y--; arr[y][x] = vect[idx]; idx++; } if (idx >= vect.size() || x < 1) break; } } } void blizzard(int d, int s){ //블리자드 y = x = N / 2 + 1; for (int i = 1; i <= s; i++) { int yy = y + dy[d] * i; int xx = x + dx[d] * i; arr[yy][xx] = 0; } } int main() { scanf("%d %d", &N, &M); y = x = N / 2; for (int i = 1; i <= N; i++) { for (int j = 1; j <= N; j++) { scanf("%d", &arr[i][j]); } } for (int i = 0; i < M; i++) { int d, s; scanf("%d %d", &d, &s); blizzard(d, s); move(); } printf("%d", ans); } | cs |
반응형
'백준' 카테고리의 다른 글
[ 백준 ] 20061번 - 모노미노도미노 2 (C++) (0) | 2022.09.28 |
---|---|
[ 백준 ] 17825번 - 주사위 윷놀이 (C++) (0) | 2022.09.27 |
[ 백준 ] 17822번 - 원판 돌리기 (C++) (0) | 2022.09.25 |
[ 백준 ] 20057번 - 마법사 상어와 토네이도 (C++) (0) | 2022.09.24 |
[ 백준 ] 20058번 - 마법사 상어와 파이어스톰 (C++) (0) | 2022.09.23 |