문제 링크입니다: https://www.acmicpc.net/problem/17135
17135번: 캐슬 디펜스
첫째 줄에 격자판 행의 수 N, 열의 수 M, 궁수의 공격 거리 제한 D가 주어진다. 둘째 줄부터 N개의 줄에는 격자판의 상태가 주어진다. 0은 빈 칸, 1은 적이 있는 칸이다.
www.acmicpc.net
next_permutation을 이용한 시뮬레이션 문제였습니다.
이런 유형은 삼성 A형에 자주 출제되는 유형이므로 익혀두는 것이 좋을 것 같습니다.
흐름에 따라 코드를 작성하면 되므로 별도의 설명은 주석으로 대체하겠습니다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |


개발환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
반응형
'알고리즘 > BOJ' 카테고리의 다른 글
백준 2858번 기숙사 바닥 (2) | 2019.08.08 |
---|---|
백준 17136번 색종이 붙이기 (12) | 2019.08.06 |
백준 17294번 귀여운 수~ε٩(๑> ₃ <)۶з (2) | 2019.08.04 |
백준 17069번 파이프 옮기기 2 (0) | 2019.08.04 |
백준 17070번 파이프 옮기기 1 (0) | 2019.08.04 |