코딩 공부/백준

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

김 정 환 2021. 5. 25. 15:34
반응형

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

 

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

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

www.acmicpc.net

 

 

알고리즘 종류

구현

 

사고 과정

 

 

 

구현(C++)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <iostream>
#include <vector>
#include <cmath>
 
using namespace std;
 
int N, M, K;
 
struct Ball{
    int y, x;
    int m, s, d;
};
 
vector<Ball> balls;
vector<Ball> mat[53][53];
 
int dir[8][2= {{-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}};
 
 
void solution(){
    
    while(K--){
        
        // Ball 움직이기  
        for(int i=0; i<balls.size(); i++){
            int y=balls[i].y;
            int x=balls[i].x;
            int m=balls[i].m;
            int s=balls[i].s;
            int d=balls[i].d;
            
            int move = s % N;
            int ny = y + dir[d][0]*move;
            int nx = x + dir[d][1]*move;
            
            if(ny>N) ny -= N;
            if(nx>N) nx -= N;
            if(ny<1) ny += N;
            if(nx<1) nx += N;
                
            mat[ny][nx].push_back({ny, nx, m, s, d});
        }
        
        
        // 움직임이 완료된 Ball들 합치기  
        for(int i=1; i<=N; i++){
            for(int j=1; j<=N; j++){
                if(mat[i][j].size() >= 2){
                    int sum_m=0, sum_s=0;
                    int odd=0, even=0;
                    int size=mat[i][j].size();
                    
                    for(int t=0; t<size; t++){
                        sum_m += mat[i][j][t].m;
                        sum_s += mat[i][j][t].s;
                    
                        if(mat[i][j][t].d % 2 == 0) even++;
                        else odd++;
                    }
                    
                    mat[i][j].clear();
                    
                    if(sum_m/5 == 0continue;
                    
                    if(odd==0 || even==0){
                        for(int nd=0; nd<7; nd+=2){
                            mat[i][j].push_back({i, j, sum_m/5, sum_s/size, nd});
                        }
                    }
                    else{
                        for(int nd=1; nd<8; nd+=2){
                            mat[i][j].push_back({i, j, sum_m/5, sum_s/size, nd});
                        }
                    }
                    
                }
                    
            }
        }
        
        // 합치기가 완료된 Ball을 저장하기  
        balls.clear();
        for(int i=1; i<=N; i++){
            for(int j=1; j<=N; j++){
                for(int t=0; t<mat[i][j].size(); t++){
                    balls.push_back(mat[i][j][t]);
                }
                mat[i][j].clear();
            }
        }
    }
    
    // 남은 질량의 합 구하기  
    int ans=0;
    for(int i=0; i<balls.size(); i++)
        ans += balls[i].m;
    
    cout << ans << endl;
}
 
 
int main(void){
    
    cin >> N >> M >> K;
    
    for(int i=0; i<M; i++){
        int y, x, m, s, d;
        cin >> y >> x >> m >> s >> d;
        balls.push_back({y, x, m, s, d});
    }
    
    solution();
}
cs

 

 

 

시행착오

반응형