[백준] 20056 마법사 상어와 파이어볼

문제 링크

20056번: 마법사 상어와 파이어볼

알고리즘

시뮬레이션

풀이

이번 삼성 복기 문제이다. 우선 파이어볼을 구조체로 정의하고 최대 크기인 50x50 벡터로 정보를 관리하였다. 이동 후의 파이어볼은 또 다른 벡터에 저장하여 기존 벡터와 겹치지 않게 하였다. 2개 이상의 파이어볼이 한 칸에 있으면 4개로 나누어지므로 시간 복잡도는 O(KN2)O(K*N^2)이라 볼 수 있다.

코드

#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

struct Fireball {
    int m, s, d;
};

const int dr[] = {-1, -1, 0, 1, 1, 1, 0, -1};
const int dc[] = {0, 1, 1, 1, 0, -1, -1, -1};
vector<Fireball> map[50][50];
int n, m, k;

bool even(vector<int>& dir) {
    for (auto d : dir)
        if (d % 2 != 0) return false;
    return true;
}

bool odd(vector<int>& dir) {
    for (auto d : dir)
        if (d % 2 == 0) return false;
    return true;
}

void go() {
    vector<Fireball> c_map[50][50];
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            for (auto& f : map[i][j]) {
                int nr = ((i + dr[f.d] * f.s) % n + n) % n;
                int nc = ((j + dc[f.d] * f.s) % n + n) % n;
                c_map[nr][nc].push_back({f.m, f.s, f.d});
            }
            map[i][j].clear();
        }
    }

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (c_map[i][j].size() == 0)
                continue;
            else if (c_map[i][j].size() == 1) {
                map[i][j].push_back(c_map[i][j][0]);
                continue;
            }
            int m = 0, s = 0;
            vector<int> dir;
            for (auto& f : c_map[i][j]) {
                m += f.m;
                s += f.s;
                dir.push_back(f.d);
            }
            m /= 5;
            s /= c_map[i][j].size();
            if (m == 0) continue;
            if (even(dir) || odd(dir)) {
                for (int d = 0; d < 8; d += 2)
                    map[i][j].push_back({m, s, d});
            }
            else {
                for (int d = 0; d < 8; d += 2)
                    map[i][j].push_back({m, s, d + 1});
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m >> k;
    for (int i = 0; i < m; ++i) {
        int r, c, m, s, d;
        cin >> r >> c >> m >> s >> d;
        map[r - 1][c - 1].push_back({m, s, d});
    }

    for (int i = 0; i < k; ++i) go();

    int answer = 0;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            for (auto& f : map[i][j]) answer += f.m;

    cout << answer << endl;
    return 0;
}

Written by@WOOJIN
自强不息,厚德载物

GitHub