Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- dfs
- 버킷 정렬
- Stack 이란
- 백준 17779
- 백준
- 백준 17471
- heap
- 해시 구현
- 시간 복잡도
- c#
- 구현
- 백준 2447
- 별 찍기 10
- 백준 17822
- 원판 돌리기
- 풀이
- 게리멘더링2
- 1764
- 5397
- C/C++ 구현
- 스택의 특징
- 해시구현
- 조세퍼스 순열
- 자료구조
- qorwns
- 백준 1406
- AVL 시간 복잡도
- ㅣ풀이
- 백준 5397
- 백준 1158
Archives
- Today
- Total
홍시홍의 프로그래밍
[백준 17135] 캐슬 디펜스 본문
분류
분류, dfs
요구사항
적들이 0행~n-1행으로 이동할때, 궁수를 적절히 배치하여 처치할 수 있는 적들의 최대 수 구하기
풀이
전체적 문제의 흐름은 아래와 같다
1. dfs로 궁수 위치 정해주기
2. 적에서 궁수까지 거리 구하기
3. 제일 가까우면서 왼쪽에 있는 적 없애기
4. 적 이동
2~4번 반복
3번은 sort를 이용하여 처리하였다. 잡을 경우, map[r][c]가 1이면 0으로 바꾸어주고 cnt를 1증가 시켰다.
#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;
struct go {
int dist;
int c;
int r;
};
int n, m, d;
int map[17][17];
int visit[16];
int ans = 0;
bool check() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == 1)
return false;
}
}
return true;
}
bool cmp(go a, go b) {
if (a.dist < b.dist) {
return true;
}
else if (a.dist == b.dist) {
if (a.c < b.c) return true;
}
return false;
}
void Get_ans(int arr[]) {
int cnt = 0;
vector<go> v[16];
int pos[16];
for (int i = 0; i < m; i++) {
if (visit[i] == 1) {
pos[cnt++] = i;
}
}
cnt = 0;
while (true) {
if (check()) {
break;
}
//모든 궁수로 부터 적까지 거리 구하기
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == 1) {
for (int k = 0; k <3; k++) {
int dist = abs(i - n) + abs(j - pos[k]);
if (dist <= d) {
v[pos[k]].push_back({ dist,j,i });
}
}
}
}
}
//제일 가까우면서 왼쪽에 있는 적 찾기
for (int i = 0; i <3; i++) {
if (!v[pos[i]].empty()) {
sort(v[pos[i]].begin(), v[pos[i]].end(), cmp);
int x = v[pos[i]][0].r;
int y = v[pos[i]][0].c;
if (map[x][y] == 1) {
cnt++;
map[x][y] = 0;
}
v[pos[i]].clear();
}
}
//적들 밑으로 한 칸 이동하기
for (int i = n - 1; i >= 0; i--) {
for (int j = 0; j < m; j++) {
if (map[i][j] == 1) {
if (i == n - 1)
map[i][j] = 0;
else {
map[i][j] = 0;
map[i + 1][j] = 1;
}
}
}
}
}
ans = max(ans, cnt);
}
void solve(int cnt, int now) {
if (now == m) {
if (cnt == 3) {
int mapc[17][17];
memcpy(mapc, map, sizeof(map));
Get_ans(visit);
memcpy(map, mapc, sizeof(map));
}
return;
}
visit[now] = 1;
solve(cnt + 1, now + 1);
visit[now] = 0;
solve(cnt, now + 1);
}
int main() {
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]);
}
}
solve(0, 0);
cout << ans << endl;
}
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
[백준 17281] 야구 (0) | 2020.05.03 |
---|---|
[백준 17136] 색종이 붙히기 (0) | 2020.05.02 |
[백준 17070] 파이프 옮기기1 (0) | 2020.05.02 |
[백준 16637] 괄호 추가하기 (0) | 2020.05.02 |
[백준 1010] 다리 놓기 (0) | 2020.04.25 |
Comments