Algorithm/백준

[BOJ] - 17135. 캐슬 디펜스

benguin 2019. 4. 8. 18:48

[URL]

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

 

17135번: 캐슬 디펜스

첫째 줄에 격자판 행의 수 N, 열의 수 M, 궁수의 공격 거리 제한 D가 주어진다. 둘째 줄부터 N개의 줄에는 격자판의 상태가 주어진다. 0은 빈 칸, 1은 적이 있는 칸이다.

www.acmicpc.net

[풀이 과정]

* 재귀DFS + 시뮬레이션

(주의 사항)

- 각각의 (a1, a2, a3)에 대한 enemy벡터 초기화

- target 조건 1, 2

1. map[][] == 1인 곳 (x,y)좌표 데이터 enemy 벡터로 저장

2. go()를 통해 가능한 궁수의 위치 3곳 구한다. (재귀 DFS) --> (a1, a2, a3)

3. 각각의 (a1, a2, a3)에 대해 캐슬디펜스 시작

4. a1, a2, a3 각각의 target을 구한다. --> (t1, t2, t3)

< target의 조건 ! >

* 거리가 D이하 이면서 가장 가까운 거리의 적

* 여럿일 경우, 가장 왼쪽의 적 -----------> 이 조건을 처음에 빼먹어서 헤맸다.

5. enemy벡터를 검사하며 t1, t2, t3인 경우, 벡터에서 삭제 후, sum++

6. (a1, a2, a3) 에 대해 나온 (sum: 제거 할 수 있는 적의 수) cand[]배열에 저장

7. cand[] 중 가장 큰 수 출력!!

[소스 코드]

 

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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#include <stdio.h>
#include <vector>
#include <algorithm>
 
using namespace std;
 
int N, M, D;
int map[20][20];
bool check[20= { 0, };
 
int arrow[3];
 
int cand[9999];
int candCnt;
 
struct info {
    int x;
    int y;
};
 
vector <info> enemy;
vector <info> enemyCopy;
 
void init() {
    candCnt = 0;
 
    scanf("%d %d %d"&N, &M, &D);
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            scanf("%d"&map[i][j]);
 
            if (map[i][j] == 1)
            {
                info temp;
                temp.x = i;
                temp.y = j;
 
                enemy.push_back(temp);
            }
        }
    }
}
 
bool cmp(info a, info b) {
    return a.y < b.y;
}
 
info findNearTarget(int A)
{
    int tempDist;
    vector <info> nearCand;
 
    int nearDist = 987654321;
 
    for (int i = 0; i < enemyCopy.size(); i++)
    {
        tempDist = abs(N - enemyCopy[i].x) + abs(A - enemyCopy[i].y);
 
        if (tempDist <= D)
        {
            if (nearDist >= tempDist)
            {
                nearDist = tempDist;
            }
        }
    }
 
    for (int i = 0; i < enemyCopy.size(); i++)
    {
        tempDist = abs(N - enemyCopy[i].x) + abs(A - enemyCopy[i].y);
 
        if (tempDist == nearDist)
        {
            info temp;
            temp.x = enemyCopy[i].x;
            temp.y = enemyCopy[i].y;
 
            nearCand.push_back(temp);
        }
    }
 
    sort(nearCand.begin(), nearCand.end(), cmp);
 
    info nearEnemy;
 
    if (nearCand.size() == 0)
    {
        nearEnemy.x = -99;
        nearEnemy.y = -99;
    }
    else
    {
        nearEnemy.x = nearCand.front().x;
        nearEnemy.y = nearCand.front().y;
    }
 
    return nearEnemy;
}
 
int goCalc()
{
    int sum = 0;
 
    while (enemyCopy.size() != 0)
    {
        // 삭제 할 타겟 구해온다!
        info target1 = findNearTarget(arrow[0]);
        info target2 = findNearTarget(arrow[1]);
        info target3 = findNearTarget(arrow[2]);
 
        // 타겟 삭제
        if (target1.x != -99)
        {
            for (int i = 0; i < enemyCopy.size();)
            {
                if (target1.x == enemyCopy[i].x && target1.y == enemyCopy[i].y)
                {
                    enemyCopy.erase(enemyCopy.begin() + i);
                    sum++;
                }
                else
                    i++;
            }
        }
 
        if (target2.x != -99)
        {
            for (int i = 0; i < enemyCopy.size();)
            {
                if (target2.x == enemyCopy[i].x && target2.y == enemyCopy[i].y)
                {
                    enemyCopy.erase(enemyCopy.begin() + i);
                    sum++;
                }
                else
                    i++;
            }
        }
 
        if (target3.x != -99)
        {
            for (int i = 0; i < enemyCopy.size();)
            {
                if (target3.x == enemyCopy[i].x && target3.y == enemyCopy[i].y)
                {
                    enemyCopy.erase(enemyCopy.begin() + i);
                    sum++;
                }
                else
                    i++;
            }
        }
 
        // 적군 한칸씩 내리기
        for (int i = 0; i < enemyCopy.size();)
        {
            enemyCopy[i].x = enemyCopy[i].x + 1;
 
            if (enemyCopy[i].x == N)
                enemyCopy.erase(enemyCopy.begin() + i);
 
            else
                i++;
        }
    }
 
    return sum;
}
 
void go(int cnt)
{
    if (cnt == 3)
    {
        for (int i = 0; i < enemy.size(); i++)
        {
            info temp;
            temp.x = enemy[i].x;
            temp.y = enemy[i].y;
 
            enemyCopy.push_back(temp);
        }
 
        cand[candCnt] = goCalc();
        candCnt++;
        return;
    }
 
    for (int i = arrow[cnt - 1]; i < M; i++)
    {
        if (check[i] == false)
        {
            check[i] = true;
            arrow[cnt] = i;
 
            cnt++;
 
            go(cnt);
 
            cnt--;
            check[i] = false;
        }
    }
}
 
int main()
{
    init();
    go(0);
    int Max = 0;
    for (int i = 0; i < candCnt; i++)
    {
        if (cand[i] >= Max)
        {
            Max = cand[i];
        }
    }
    printf("%d\n", Max);
 
    return 0;
}
cs

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

[BOJ] - 14888. 연산자 끼워넣기  (0) 2019.04.09
[BOJ] - 14889. 스타트와 링크  (0) 2019.04.09
[BOJ] - 17136. 색종이 붙이기  (0) 2019.04.09
[BOJ] - 16235. 나무 재테크  (0) 2019.04.08
[BOJ] - 15683. 감시  (0) 2019.04.08