알고리즘/BOJ

백준 17135번 캐슬 디펜스

꾸준함. 2019. 8. 6. 02:04

문제 링크입니다: https://www.acmicpc.net/problem/17135

 

17135번: 캐슬 디펜스

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

www.acmicpc.net

next_permutation을 이용한 시뮬레이션 문제였습니다.

이런 유형은 삼성 A형에 자주 출제되는 유형이므로 익혀두는 것이 좋을 것 같습니다.

흐름에 따라 코드를 작성하면 되므로 별도의 설명은 주석으로 대체하겠습니다.

 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAX = 15;
int N, M, D;
int arr[MAX][MAX];
int copyArr[MAX][MAX];
int main(void)
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M >> D;
vector<pair<int, int>> enemy;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
cin >> arr[i][j];
if (arr[i][j] == 1)
{
// 적들의 좌표를 모두 넣어준다
enemy.push_back({ i, j });
}
}
}
/*
next_permutation을 이용할 것이기 때문에
00..0111 부터 시작
*/
vector<int> archer;
for (int i = 0; i < M - 3; i++)
{
archer.push_back(0);
}
for (int i = 0; i < 3; i++)
{
archer.push_back(1);
}
int result = 0;
do
{
int cnt = 0;
// 적들의 좌표를 복사
vector<pair<int, int>> temp = enemy;
vector<int> v;
for (int i = 0; i < archer.size(); i++)
{
if (archer[i] == 1)
{
// 현재 궁수 위치 저장
v.push_back(i);
}
}
while (!temp.empty())
{
int y = N;
vector<int> target;
// 궁수는 동시에 공격
for (int i = 0; i < v.size(); i++)
{
int x = v[i];
int idx = 0;
int enemyX = temp[0].second;
int dist = abs(y - temp[0].first) + abs(x - temp[0].second);
for (int j = 1; j < temp.size(); j++)
{
int tempDist = abs(y - temp[j].first) + abs(x - temp[j].second);
// 더 가까운 적
if (dist > tempDist)
{
enemyX = temp[j].second;
dist = tempDist;
idx = j;
}
// 거리가 같다면 더 왼쪽에 있는 적
else if (dist == tempDist && enemyX > temp[j].second)
{
enemyX = temp[j].second;
idx = j;
}
}
// D 이내에 있는 적만 처치 가능
if (dist <= D)
{
target.push_back(idx);
}
}
// 동시에 공격하기 때문에 중복된 적 있을 수 있다
target.erase(unique(target.begin(), target.end()), target.end());
sort(target.begin(), target.end());
int shoot = 0;
// 적을 처치
for (int i = 0; i < target.size(); i++)
{
temp.erase(temp.begin() + (target[i] - shoot++));
cnt++;
}
if (temp.empty())
{
break;
}
// 한칸 아래로
vector<pair<int, int>> copyTemp;
for (int i = 0; i < temp.size(); i++)
{
if (temp[i].first < N - 1)
{
copyTemp.push_back({ temp[i].first + 1, temp[i].second });
}
}
temp = copyTemp;
}
result = max(result, cnt);
} while (next_permutation(archer.begin(), archer.end()));
cout << result << "\n";
return 0;
}
view raw .cpp hosted with ❤ by GitHub

 

 

개발환경:Visual Studio 2017

 

지적, 조언, 질문 환영입니다! 댓글 남겨주세요~

반응형