BOJ 20056 : 마법사 상어와 파이어볼 - C++

김정욱·2021년 4월 10일
0

Algorithm - 문제

목록 보기
215/249

마법사 상어와 파이어볼

코드

#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
#include <deque>
#include <numeric>
#include <map>
#define ll long long
using namespace std;
int N,M,K,ans;
struct fireBall{
    int r;
    int c;
    int m;
    int d;
    bool dF = true;
    int s;
    int cnt=0;
};
vector<fireBall> fv;
int dc[8] = {0, 1, 1, 1, 0, -1, -1, -1};
int dr[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
fireBall t_board[55][55]; // 1 ~ N 인덱스 사용
fireBall f_board[55][55];
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> N >> M >> K;

    for(int i=0;i<M;i++)
    {
        fireBall f;
        cin >> f.r >> f.c >> f.m >> f.s >> f.d;
        fv.push_back(f);
    }
    while(K--)
    {
        /* 파이어볼 이동 */
        for(int i=0;i<fv.size();i++)
        {
            int speed = fv[i].s;
            int dir = fv[i].d;
            int nr = fv[i].r;
            int nc = fv[i].c;
            speed %= N;
            while(speed--)
            {
                nr += dr[dir];
                nc += dc[dir];
                if(nr < 1) nr += N;
                if(nc < 1) nc += N;
                if(nr > N) nr -= N;
                if(nc > N) nc -= N;
            }
            /* 아무 파이어볼이 없는경우 */
            if(t_board[nr][nc].cnt == 0){
                fv[i].r = nr;
                fv[i].c = nc;
                t_board[nr][nc] = fv[i];
                t_board[nr][nc].cnt = 1;
            }else{
                /* 파이어볼이 이미 있는 경우 */
                t_board[nr][nc].cnt++;
                t_board[nr][nc].m += fv[i].m;
                t_board[nr][nc].s += fv[i].s;
                t_board[nr][nc].r = nr;
                t_board[nr][nc].c = nc;
                if(t_board[nr][nc].dF == true and t_board[nr][nc].d%2 == fv[i].d%2)
                    t_board[nr][nc].dF = true;
                else
                    t_board[nr][nc].dF = false;
            }
        }
        fv.clear();
        /* 파이어볼 분할! */
        for(int i=1;i<=N;i++)
        {
            for(int j=1;j<=N;j++)
            {
                if(t_board[i][j].cnt == 0) continue;
                if(t_board[i][j].cnt == 1){
                    fv.push_back(t_board[i][j]);
                    continue;
                }
                int m,s,d,st=0;
                m = t_board[i][j].m/5;
                if(m == 0) continue;
                s = t_board[i][j].s/t_board[i][j].cnt;
                pair<int,int> cur = {i,j};
                if(t_board[i][j].dF == false) st++;

                /* 제자리에서 여러 방향을 가진 파이어볼로 분할 */
                for(int n=st;n<8;n+=2)
                {
                    d = n;
                    fv.push_back({i, j, m, d, true, s, 1});
                }
            }
        }
        /* 두개의 보드 초기화 */
        for(int i=1;i<=N;i++)
        {
            for(int j=1;j<=N;j++)
            {
                fireBall tmp = {0, 0, 0, -1, true, 0, 0};
                f_board[i][j] = tmp;
                t_board[i][j] = tmp;
            }
        }
    }
    /* 남아있는 파이어볼의 질량 구하기 */
    for(int i=0;i<fv.size();i++) ans += fv[i].m;
    cout << ans;
    return 0;
}
  • 유의
    • 파이어볼이 분할될 때 제자리에서 여러 방향을 가진 파이어볼분할되는 것임
      --> 여러 방향으로 뻗어나가서 그 자리에 파이어볼이 저장되는 것이 아님
      (문제 설명너무 모호해서 많은 사람들이 헷갈려하는 듯 보임)
profile
Developer & PhotoGrapher

0개의 댓글