https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRDL1aeugDFAUo



구현하는게 생각보다 까다로운 문제다.

문제에 제시된 변수가 많아서 코드를 깔끔하게 짜지 못한 것 같아서 아쉬운데

우선 접근 방향은 다음과 같다.



1) A,B의 이동 경로와 설치된 BC의 좌표 및 거리,충전량을 입력받는다

2) 각각의 BC를 현재 좌표에서 거리가 닿는 만큼 좌표마다 BC번호와 충전량을 저장해준다.

   (지도의 y,x좌표에 각각 BC번호와 충전량을 insert 해주는 방식)

3)초기의 A,B 좌표에서 이동을 시작하며 각각의 좌표에 저장된 BC 정보에 따라 충전량을 더해준다



위의 방식대로 구현할 때

좌표마다 BC번호와 충전량을 저장해주기 위해 vector<pair<int,int>> 형식으로 좌표를 구성했다. 

그리고 거리가 닿는 만큼 충전량을 저장해주기 위해 큐를 이용해서 거리 순서대로 충전량을 저장해주면 된다.


주의할 점은 이동을 하지 않은 초기 좌표에서의 충전량을 계산해야 하기 때문에

이동을 하기전인 0부터 이동 순서인 M만큼 충전량을 구해줘야 한다. 즉, M+1번 충전량을 계산해주면 된다.


마지막으로 A,B의 좌표에서 충전량의 최대값을 구할 때

동일한 BC번호일 때 2만큼 나눠줘야 올바른 충전량을 구할 수 있다.



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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <iostream>
#include <vector>
#include <queue>
#include <math.h>
using namespace std;
#define N 10
 
struct str{
    int y;
    int x;
    int c;
    int p;
    str(int y,int x,int c,int p):y(y),x(x),c(c),p(p){};
};
 
int M,A;
vector<pair<int,int>> map[N][N]; //(y,x) 좌표에서 make_pair(BC번호, 충전량)
vector<int> move_A; //A의 이동 방향
vector<int> move_B; //B의 이동 방향
vector<str> BC;
int dy[5]={0,-1,0,1,0};
int dx[5]={0,0,1,0,-1};
 
//BC 충전 범위 계산
void cal_bc(){
    
    for(int i=0;i<A;i++){
        
        str s=BC[i];
        vector<vector<int>> visited(N,vector<int>(N,0));
        
        visited[s.y][s.x]++;
        queue<str> q;
        q.push(s);
        
        while(!q.empty()){
            
            int y=q.front().y;
            int x=q.front().x;
            int c=q.front().c;
            int p=q.front().p;
            q.pop();
            
            if(c<0)
                continue;
            
            map[y][x].push_back(make_pair(i,p)); //y,x좌표의 BC번호(i)와 충전량 삽입
            for(int dir=1;dir<=4;dir++){
                int ny=y+dy[dir];
                int nx=x+dx[dir];
                
                if(ny<0 || ny>=|| nx<0 || nx>=N)
                    continue;
                
                if(visited[ny][nx])
                    continue;
                
                visited[ny][nx]++;
                q.push(str(ny,nx,c-1,p));
            }
            
        }
        
    }
    
}
 
//이동에 따른 충전량의 합 구하기
int cal_move(){
    
    int y1=0,x1=0//A의 y,x좌표
    int y2=N-1,x2=N-1//B의 y,x좌표
    int ans=0;
 
    for(int i=0;i<=M;i++){ //이동하지 않을 때 계산하기 위해 0부터 시작
        
        int sum=0;
        if(map[y1][x1].size()==0){ //A좌표 비어 있을 때
            for(int j=0;j<map[y2][x2].size();j++)
                sum=max(sum,map[y2][x2][j].second);
        }
        else if(map[y2][x2].size()==0){ //B좌표 비어 있을 때
            for(int j=0;j<map[y1][x1].size();j++)
                sum=max(sum,map[y1][x1][j].second);
        }
        else if(map[y1][x1].size()>0 && map[y2][x2].size()>0){
            
            for(int j=0;j<map[y1][x1].size();j++)
                for(int k=0;k<map[y2][x2].size();k++){
                    
                    int bc1=map[y1][x1][j].first;
                    int bc2=map[y2][x2][k].first;
                    int p1=map[y1][x1][j].second;
                    int p2=map[y2][x2][k].second;
                    
                    if(bc1==bc2)
                        sum=max(sum,(p1+p2)/2);
                    else
                        sum=max(sum,p1+p2);
                }
 
            
        }
        
        ans+=sum;
        
        if(i<M){
            y1+=dy[move_A[i]];
            x1+=dx[move_A[i]];
            y2+=dy[move_B[i]];
            x2+=dx[move_B[i]];
        }
    }
 
    return ans;
}
 
int main(){
    
    int T;
    cin>>T;
    
    for(int testCase=1;testCase<=T;testCase++){
        
        scanf("%d %d",&M,&A);
        
        for(int i=0;i<N;i++)
            for(int j=0;j<N;j++)
                map[i][j].clear();
        
        move_A=vector<int> (M,0);
        move_B=vector<int> (M,0);
        BC.clear();
        
        for(int i=0;i<M;i++)    scanf("%d",&move_A[i]);
        for(int i=0;i<M;i++)    scanf("%d",&move_B[i]);
        
        for(int i=1;i<=A;i++){
            int x,y,c,p;
            scanf("%d %d %d %d",&x,&y,&c,&p);
            BC.push_back(str(y-1,x-1,c,p));
        }
        
        cal_bc();
        cout<<"#"<<testCase<<" "<<cal_move()<<endl;
    }
    
    return 0;
}
 
cs



'알고리즘(SWEA) > 시뮬레이션' 카테고리의 다른 글

SWEA 2383번 - 점심 식사시간  (2) 2019.10.13
SWEA 5650번 - 핀볼게임  (0) 2019.09.01

+ Recent posts