어흥

[백준 20056] 마법사 상어와 파이어볼 (C++) 본문

알고리즘/백준

[백준 20056] 마법사 상어와 파이어볼 (C++)

라이언납시오 2021. 4. 8. 18:09
728x90
반응형

문제 링크: www.acmicpc.net/problem/20056

 

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

첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치

www.acmicpc.net

1. 주의할 점

- 매 TC, While문마다 초기화를 잘 수행해준다

- 범위밖으로 벗어나는 경우에 대한 처리를 잘 수행한다

- 주어진 규칙대로 전부 정확히 구현한다

 

2. 구현

- 범위밖으로 벗어나는 경우, 반대 방향으로 삽입되도록 구현한다

- 모든 파이어볼에 대한 정보를 Fire 벡터에 담는다

- Arr[][] 벡터 배열을 통해 파이어볼의 이동이 끝난 후, 몇번 파이어볼이 어디에 위치해 있는지 저장하는 역할을 한다

- Mv() 함수를 시작하면서 Arr[][]와 dup 벡터를 초기화한다

- Mv() 함수 내에서 For문을 통해 각 파이어볼의 이동후 위치를 구한다. 이때, 범위를 벗어날 수 있으므로 rtnPos() 함수를 통해 위치를 재조정한다

- Arr[][] 벡터배열을 통해 해당 위치에 파이어볼이 1개라면 Dup 벡터에 그대로 저장하고, 2개 이상이라면 규칙에 따라 질량, 방향, 속도를 구한다. 이때, 질량이 0이면 전부 소멸시키고 1이상이라면 4개의 파이어볼을 해당 자리에서 추가 생성한다

- While문을 마쳤다면 남은 파이어볼의 전체 질량을 Result에 더한다

 

#include <iostream>
#include <vector>
using namespace std;
struct info{
    int x,y,m,d,s;
};
info tmp;
int num,fb,k,result=0;
vector<info> fire,dup;
int dx[8]={0,1,1,1,0,-1,-1,-1};
int dy[8]={-1,-1,0,1,1,1,0,-1};

int rtnPos(int a){
    while(a<1 || a>num){
        if(a<1) a+=num;
        else a-=num;
    }
    return a;
}

void mv(){
    vector<int> arr[51][51];
    
    for(int i=0;i<fire.size();i++){
        int cx = fire[i].x;
        int cy = fire[i].y;
        int cd = fire[i].d;
        int cm = fire[i].m;
        int cs = fire[i].s;
        int nx = cx+dx[cd]*cs;
        int ny = cy+dy[cd]*cs;
        fire[i].x=rtnPos(nx);
        fire[i].y=rtnPos(ny);
        arr[fire[i].y][fire[i].x].push_back(i);
    }
    
    dup.clear();
    for(int i=1;i<=num;i++){
        for(int j=1;j<=num;j++){
            int len=arr[i][j].size();
            if(len>1){
                int sm=0,ss=0;
                bool allOdd=true,allEven=true;
                for(int t=0;t<len;t++){
                    sm+=fire[arr[i][j][t]].m;
                    ss+=fire[arr[i][j][t]].s;
                    if(fire[arr[i][j][t]].d%2==0) allOdd=false;
                    if(fire[arr[i][j][t]].d%2==1) allEven=false;
                }
                sm/=5;
                if(sm){
                    ss/=len;
                    int t=1;
                    if(allEven || allOdd)   t=0;
                    tmp.x = fire[arr[i][j][0]].x;
                    tmp.y = fire[arr[i][j][0]].y;
                    tmp.s = ss;
                    tmp.m = sm;
                    for(;t<8;t+=2){
                        tmp.d = t;
                        dup.push_back(tmp);
                    }
                }
            }
            else if(len==1){
                tmp.x = fire[arr[i][j][0]].x;
                tmp.y = fire[arr[i][j][0]].y;
                tmp.m = fire[arr[i][j][0]].m;
                tmp.d = fire[arr[i][j][0]].d;
                tmp.s = fire[arr[i][j][0]].s;
                dup.push_back(tmp);
            }
        }
    }
    fire=dup;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    cin>>num>>fb>>k;
    int r,c,m,s,d;
    for(int i=0;i<fb;i++){
        cin>>r>>c>>m>>s>>d;
        tmp.x=c;
        tmp.y=r;
        tmp.m=m;
        tmp.d=d;
        tmp.s=s;
        fire.push_back(tmp);
    }
    while(k--){
        mv();
    }
    for(int i=0;i<fire.size();i++)
        result+=fire[i].m;
    cout<<result;
    return 0;
}
728x90
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준 5213] 과외맨 (C++)  (0) 2021.04.14
[백준 16940] BFS 스페셜 저지 (C++)  (0) 2021.04.13
[백준 19237] 어른 상어 (C++)  (0) 2021.04.06
[백준 6059] Pasture Walking (C++)  (0) 2021.04.02
[백준 2479] 경로 찾기 (Java)  (0) 2021.04.02
Comments