코딩/백준

[백준]17135번 캐슬 디펜스 - C++

최선을 다하는 2023. 2. 8. 15:53

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

 

17135번: 캐슬 디펜스

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

www.acmicpc.net

문제

캐슬 디펜스는 성을 향해 몰려오는 적을 잡는 턴 방식의 게임이다. 게임이 진행되는 곳은 크기가 N×M인 격자판으로 나타낼 수 있다. 격자판은 1×1 크기의 칸으로 나누어져 있고, 각 칸에 포함된 적의 수는 최대 하나이다. 격자판의 N번행의 바로 아래(N+1번 행)의 모든 칸에는 성이 있다.

성을 적에게서 지키기 위해 궁수 3명을 배치하려고 한다. 궁수는 성이 있는 칸에 배치할 수 있고, 하나의 칸에는 최대 1명의 궁수만 있을 수 있다. 각각의 턴마다 궁수는 적 하나를 공격할 수 있고, 모든 궁수는 동시에 공격한다. 궁수가 공격하는 적은 거리가 D이하인 적 중에서 가장 가까운 적이고, 그러한 적이 여럿일 경우에는 가장 왼쪽에 있는 적을 공격한다. 같은 적이 여러 궁수에게 공격당할 수 있다. 공격받은 적은 게임에서 제외된다. 궁수의 공격이 끝나면, 적이 이동한다. 적은 아래로 한 칸 이동하며, 성이 있는 칸으로 이동한 경우에는 게임에서 제외된다. 모든 적이 격자판에서 제외되면 게임이 끝난다. 

게임 설명에서 보다시피 궁수를 배치한 이후의 게임 진행은 정해져있다. 따라서, 이 게임은 궁수의 위치가 중요하다. 격자판의 상태가 주어졌을 때, 궁수의 공격으로 제거할 수 있는 적의 최대 수를 계산해보자.

격자판의 두 위치 (r1, c1), (r2, c2)의 거리는 |r1-r2| + |c1-c2|이다.

입력

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

출력

첫째 줄에 궁수의 공격으로 제거할 수 있는 적의 최대 수를 출력한다.


구현 문제로 조합 + 시뮬레이션을 하면 된다. 아이디어는 쉽지만 구현하는데 자신의 코드에서 길을 잃지 않아야 한다.

arch 벡터에 재귀 함수를 통해 궁수의 위치를 정한다.

배열을 N*M이고 궁수의 위치는 항상 일렬로 서있으므로 적이 밀려온다고 생각하지 말고 궁수가 한 칸씩 전진한다고 생각하자.

BFS를 통해 사거리 내에 가장 가까운 적을 선정한다. 여러 궁수가 같은 적을 선택할 수 있으므로 아직 배열에서 적을 삭제하지 않고 큐에만 추가한다.

이렇게 3명의 궁수가 죽일 대상이 정해졌다면 삭제하고 죽인 만큼 값을 증가시킨다.

해당 궁수의 배치로 죽인 값을 현재 최댓값과 비교하여 최신화한다.


처음부터 문제 구상을 하고 들어가서 코드 작성에는 어려움이 없었으나 틀렸습니다가 나왔다. 다시 보니 궁수 별로 vis 배열을 두어야 했으나 모든 궁수가 vis 배열을 공유하여 생긴 문제였다. 또 dx dy를 잘 못 설정하였던 문제도 있었다. 이 문제들을 해결하니 문제를 맞힐 수 있었다!