반응형
https://www.acmicpc.net/problem/20056
20056번: 마법사 상어와 파이어볼
첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치
www.acmicpc.net
[ 문제풀이 ]
1. fireball struct를 만들어 vector 배열 안에 넣어줍니다.
2. 모든 좌표를 돌면서 파이어볼이 있다면 이동 해줍니다.
3. 이동이 끝나고 파이어볼이 2개 이상 있다면 합쳐줍니다.
4. 파이어볼이 나누어진 후 질량이 0이 되면 없애줍니다.
5. 위 과정을 반복해줍니다.
[ 소스코드 ]
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 | #include<iostream> #include<vector> #include<cstring> using namespace std; struct fire { int m; int s; int d; }; int N, M, K; vector<fire> arr[51][51]; vector<fire> temp[51][51]; int dy[8] = { -1,-1,0,1,1,1,0,-1 }; int dx[8] = { 0,1,1,1,0,-1,-1,-1 }; int dir[2][4] = { 0,2,4,6,1,3,5,7 }; int getM(int y, int x) //질량의 합 { int ret = 0; for (auto next : arr[y][x]) { ret += next.m; } return ret; } bool odd(vector<int> D) //방향이 모두 홀수인 지 { for (auto next : D) { if (next % 2 == 0) { return false; } } return true; } bool even(vector<int> D) //방향이 모두 짝수인 지 { for (auto next : D) { if (next % 2 == 1) { return false; } } return true; } void comb(int y, int x) //파이어볼이 2개 이상일 때 합치기 { int cnt = temp[y][x].size(); int M, S; M = S = 0; vector<int> D; for (auto &next : temp[y][x]) { int m = next.m; int s = next.s; int d = next.d; M += m; S += s; D.push_back(d); } M /= 5; S /= cnt; if (M != 0) { if (odd(D) || even(D)) { for (int i = 0; i < 4; i++) { arr[y][x].push_back({ M,S,dir[0][i] }); } } else { for (int i = 0; i < 4; i++) { arr[y][x].push_back({ M,S,dir[1][i] }); } } } } void after() { //모든 파이어볼이 이동한 후 memset(arr, 0, sizeof(arr)); for (int i = 1; i <= N; i++) { for (int j = 1; j <= N; j++) { if (temp[i][j].size() >= 2) { comb(i, j); } else if (temp[i][j].size() == 1) { arr[i][j] = temp[i][j]; } } } } void move(int y, int x) //파이어볼 이동 { for (auto &next : arr[y][x]) { int m = next.m; int s = next.s; int d = next.d; int yy = y + dy[d] * s; int xx = x + dx[d] * s; if (yy > N) { yy%= N; } if (yy < 1) { yy = -yy % N; yy = N - yy; } if (xx > N) { xx%= N; } if (xx < 1) { xx = -xx % N; xx = N - xx; } temp[yy][xx].push_back({ m,s,d }); } } void check() //파이어볼이 있는 지 { memset(temp, 0, sizeof(temp)); for (int i = 1; i <= N; i++) { for (int j = 1; j <= N; j++) { if (arr[i][j].size()) { move(i, j); } } } after(); } int main() { scanf("%d %d %d", &N, &M, &K); for (int i = 0; i < M; i++) { int r, c, m, s, d; scanf("%d %d %d %d %d", &r, &c, &m, &s, &d); arr[r][c].push_back({ m,s,d }); } for (int i = 0; i < K; i++) { check(); } int ans = 0; for (int i = 1; i <= N; i++) { for (int j = 1; j <= N; j++) { if (arr[i][j].size()) { ans += getM(i, j); } } } printf("%d", ans); } | cs |
반응형
'백준' 카테고리의 다른 글
[ 백준 ] 20057번 - 마법사 상어와 토네이도 (C++) (0) | 2022.09.24 |
---|---|
[ 백준 ] 20058번 - 마법사 상어와 파이어스톰 (C++) (0) | 2022.09.23 |
[ 백준 ] 17837번 - 새로운 게임 2 (C++) (0) | 2022.09.21 |
[ 백준 ] 1107번 - 리모컨 (C++) (0) | 2022.09.20 |
[ 백준 ] 1012번 - 유기농 배추 (C++) (0) | 2022.09.19 |