본문 바로가기

정리해두는거/알고리즘

마법사 상어와 파이어볼

728x90
반응형
SMALL

https://www.acmicpc.net/problem/20056

 

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

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

www.acmicpc.net

 

  • 속력이 N보다 큰 경우 고려를 못했다(N을 초과해서 이동 했을 때 단순히 N을 더하고 빼면 안됨)
  • 처음 속력 값을 저장할때 %연산을 사용했었는데 나중에 원본 속력 값이 사용되기 때문에 그러면 안되었다
  • 맨날 auto로 값 안바뀌는거 잊지말자 다짐하는데 또 실수했다

 

#include <iostream>
#include <vector>
#include <set>

using namespace std;


int N, M, K;

int dr[8] = {-1,-1,0,1,1,1,0,-1};
int dc[8] = {0,1,1,1,0,-1,-1,-1};

struct Fireball
{
    bool isValid;
    int no;
    int row;
    int col;
    int mass;
    int direction;
    int speed;
};

vector<vector<set<int>>> fireballMap;

vector<Fireball> fireballData;

void input()
{
    cin >> N >> M >> K;
   
    fireballMap.resize(N+1, vector<set<int>>(N+1, set<int>({})));
    
    Fireball fb;
    for(int m=0; m < M; m++)
    {
        fb.isValid = true;
        fb.no = m;
        cin >> fb.row;
        cin >> fb.col; 
        cin >> fb.mass;
        cin >> fb.speed;
        cin >> fb.direction;
        fireballData.emplace_back(fb);
        
        fireballMap[fb.row][fb.col].insert(m);
    }
}

void moveFireBall()
{
    for(int i=0; i < fireballData.size(); i++)
    {
        if(fireballData[i].isValid == false) continue;
        
        int newRow = fireballData[i].row + fireballData[i].speed * dr[fireballData[i].direction];
        if(newRow > N) newRow %= N;
        if(newRow < 1) newRow = newRow%N + N;
        
        int newCol = fireballData[i].col + fireballData[i].speed * dc[fireballData[i].direction];
        if(newCol > N) newCol %= N;
        if(newCol < 1) newCol = newCol%N + N;

        fireballMap[fireballData[i].row][fireballData[i].col].erase(fireballData[i].no);
        fireballMap[newRow][newCol].insert(fireballData[i].no);
        
        fireballData[i].row = newRow;
        fireballData[i].col = newCol;
    }
}

void makeFourFB(int row, int col)
{
    int mass = 0;
    int speed = 0;
    int evenDir = 0;
    int oddDir = 0;
    
    for (auto a : fireballMap[row][col])
    {
        mass += fireballData[a].mass;
        speed += fireballData[a].speed;
        
        if(fireballData[a].direction % 2 == 0)evenDir++;
        else oddDir++;
    }
    
    mass /= 5;
    speed /= fireballMap[row][col].size();
    
    for(auto fbNo : fireballMap[row][col])
    {
        fireballData[fbNo].isValid = false;
    }
    fireballMap[row][col].clear();
    
    if (mass > 0){
        if(evenDir == fireballMap[row][col].size() || oddDir == fireballMap[row][col].size())
        {
            Fireball fb;
            fb.isValid = true;
            fb.row = row;
            fb.col = col;
            fb.mass = mass;
            fb.speed = speed;
        
            
            fb.no = (int)fireballData.size();
            fb.direction = 0;
            fireballData.emplace_back(fb);
            fireballMap[row][col].insert(fb.no);
            
            fb.no = (int)fireballData.size();
            fb.direction = 2;
            fireballData.emplace_back(fb);
            fireballMap[row][col].insert(fb.no);
            
            fb.no = (int)fireballData.size();
            fb.direction = 4;
            fireballData.emplace_back(fb);
            fireballMap[row][col].insert(fb.no);
            
            fb.no = (int)fireballData.size();
            fb.direction = 6;
            fireballData.emplace_back(fb);
            fireballMap[row][col].insert(fb.no);
            
        }
        else
        {
            Fireball fb;
            fb.isValid = true;
            fb.row = row;
            fb.col = col;
            fb.mass = mass;
            fb.speed = speed;
        
            
            fb.no = (int)fireballData.size();
            fb.direction = 1;
            fireballData.emplace_back(fb);
            fireballMap[row][col].insert(fb.no);
            
            fb.no = (int)fireballData.size();
            fb.direction = 3;
            fireballData.emplace_back(fb);
            fireballMap[row][col].insert(fb.no);
            
            fb.no = (int)fireballData.size();
            fb.direction = 5;
            fireballData.emplace_back(fb);
            fireballMap[row][col].insert(fb.no);
            
            fb.no = (int)fireballData.size();
            fb.direction = 7;
            fireballData.emplace_back(fb);
            fireballMap[row][col].insert(fb.no);
        }
    }
}

void sharkCMD()
{
    moveFireBall();
        
    for(int r=1; r <= N; r++)
    {
        for(int c=1; c <= N; c++)
        {
            if(fireballMap[r][c].size() > 1)
            {
                makeFourFB(r,c);
            }
        }
    }
}

int totalMass()
{
    int sum = 0;
    for(auto a : fireballData)
    {
        if(a.isValid)
        {
            sum += a.mass;
        }
    }
    return sum;
}



int main(int argc, const char * argv[])
{
    input();
    
    for (int k=0; k < K; k++)
    {
        sharkCMD();
        
    }
    
    cout << totalMass();
    
    return 0;
}
728x90
반응형
LIST

'정리해두는거 > 알고리즘' 카테고리의 다른 글

토마토  (0) 2024.02.18
미로 탐색  (0) 2024.02.18
설탕 배달 (dp)  (1) 2024.02.17
설탕 배달 (그냥 구현)  (0) 2024.02.17
XCode에서 연습하게 되었다  (0) 2024.02.04