https://www.acmicpc.net/problem/20056
20056번: 마법사 상어와 파이어볼
첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치
www.acmicpc.net
#include <iostream>
#include <vector>
#include <algorithm>
#define fastio() ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
int N, M, K, ans;
int dy[8] = {-1, -1, 0, 1, 1, 1, 0, -1}; // 방향을 나타냅니다.
int dx[8] = {0, 1, 1, 1, 0, -1, -1, -1};
struct Ball { // 공과 그 구성요소를 나타냅니다.
int r, c, m, s, d;
};
vector<Ball> ball;
void input();
void move();
void solve();
int main() {
fastio();
input(); // 입력
solve(); // 풀기
return 0;
}
void input() { // 입력
cin >> N >> M >> K;
ball = vector<Ball>(M);
for (int i = 0; i < M; i++) cin >> ball[i].r >> ball[i].c >> ball[i].m >> ball[i].s >> ball[i].d;
}
void solve() { // 풀기
while (K--) move(); // 옮기기
for (int i = 0; i < ball.size(); i++) ans += ball[i].m;
cout << ans;
}
void move() { // 옮기기
vector<Ball> maps[55][55]; // 합쳐질 때를 대비해서 (같은 칸에 있는 파이어볼은 모두 하나로 합쳐진다.)
for (int i = 0; i < ball.size(); i++) {
Ball tmp;
if (0 < ball[i].r + dy[ball[i].d] * ball[i].s) { // 1 이상 일때
tmp.r = (ball[i].r + dy[ball[i].d] * ball[i].s) % N;
if (tmp.r == 0) tmp.r = N; // 1부터 시작 하였으므로
}
else tmp.r = N + (ball[i].r + dy[ball[i].d] * ball[i].s) % N; // - 일때
if (0 < ball[i].c + dx[ball[i].d] * ball[i].s) { // 1 이상 일때
tmp.c = (ball[i].c + dx[ball[i].d] * ball[i].s) % N;
if (tmp.c == 0) tmp.c = N; // 1부터 시작 하였으므로
}
else tmp.c = N + (ball[i].c + dx[ball[i].d] * ball[i].s) % N; // - 일때
tmp.m = ball[i].m; tmp.s = ball[i].s; tmp.d = ball[i].d;
maps[tmp.r][tmp.c].push_back(tmp); // 합쳐질 때를 대비해서
}
ball.clear(); // 중복 값을 처리하기 위하여 비운다
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (!maps[i][j].empty()) {
if (maps[i][j].size() <= 1) ball.push_back(maps[i][j][0]); // 같은 칸이 아닐 때
else { // 같은 칸에 있는 파이어볼은 모두 하나로 합쳐진다.
Ball tmp; tmp.r = i; tmp.c = j;
tmp.m = 0; tmp.s = 0; tmp.d = 0;
bool ways = true; // 방향 체크
for (auto& iter: maps[i][j]) {
tmp.m += iter.m;
tmp.s += iter.s;
if (maps[i][j][0].d % 2 != iter.d % 2) ways = false; // 합쳐지는 파이어볼의 방향이 모두 홀수이거나 모두 짝수이면, 방향은 0, 2, 4, 6이 되고, 그렇지 않으면 1, 3, 5, 7이 된다.
}
if (tmp.m < 5) continue; // 질량이 0인 파이어볼은 소멸되어 없어진다.
tmp.m = int(tmp.m / 5);
tmp.s = int(tmp.s / maps[i][j].size());
// 질량은 ⌊(합쳐진 파이어볼 질량의 합)/5⌋이다.
// 속력은 ⌊(합쳐진 파이어볼 속력의 합)/(합쳐진 파이어볼의 개수)⌋이다.
if (ways) {
for (int i = 0; i < 8; i += 2) {
tmp.d = i;
ball.push_back(tmp);
}
}
else {
for (int i = 1; i < 8; i += 2) {
tmp.d = i;
ball.push_back(tmp);
}
}
}
}
}
}
}
|
cs |
풀이
간단한 시뮬레이션 문제입니다
'백준(C, C++) > 골드' 카테고리의 다른 글
백준 12100: 2048(Easy) [C언어], 삼성 코딩 테스트 (0) | 2022.06.13 |
---|---|
백준 17144: 미세먼지 안녕! [C/C++], 삼성 코딩 테스트 (0) | 2022.06.13 |
백준 14503: 로봇 청소기 [C/C++], 삼성 코딩 테스트 (0) | 2022.06.12 |
백준 3078: 좋은 친구 [C/C++] (0) | 2022.06.11 |
백준 15961: 회전 초밥 [C/C++] (0) | 2022.06.07 |