[BOJ] 17135 : 캐슬 디펜스

17135 : 캐슬 디펜스

풀이

조합+BFS

삼성19-4월 SW상시테스트 1번문제

시험장에서 50분만에 푼 문제이다.

복원문제도 똑같이 바로 풀었다.

dx,dy를 이렇게 설정해두면, 우선순위를 정할 필요가 없다.

항상 왼쪽, 위, 오른쪽 순서로 큐에 넣으면 된다.

시험장에선 target이 없을 수도 있는데, i<3을 해서 런타임에러가 나서 잠깐 식은땀을 흘렸었다.

i<target.size()로 바꿔서 해결했다.

푸는 순서는 이렇다.

1.궁수 포지션을 정해준다 (조합)

2.3~5을 반복한다, arr에 1이 없으면 반복 종료.

3.각각 궁수가 쏜다(shot- bfs로 구현)-타겟:target에 포지션 저장

4.target을 없앤다( 이때 중복된 적은 카운트하면 안된다 )

5.적들이 전진한다(move)

6.이번에 더많이맞췄으면 정답갱신

코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
int n, m, d;
int ans;
vector<int> position;
vector<pair<int,int>> target;
int arr[15][15];
int backup[15][15];
int chk[15][15];
const int dx[] = { 0,-1,0 };
const int dy[] = { -1,0,1 };

void shot(int p) {
    memset(chk, 0, sizeof(chk));
    queue<pair<pair<int, int>,int>> q;
    q.push({ {n - 1,p}, 1});
    chk[n - 1][p] = 1;
    while (!q.empty()) {
        int x = q.front().first.first;
        int y = q.front().first.second;
        int cnt = q.front().second;
        q.pop();
        if (cnt > d) {
            break;
        }
        if (arr[x][y] == 1) {
            target.push_back({x,y});
            break;
        }
        for (int dir = 0; dir < 3; dir++) {
            int nx = x + dx[dir];
            int ny = y + dy[dir];
            if (nx >= 0 && nx < n&&ny >= 0 && ny < m&&chk[nx][ny] == 0) {
                q.push({ {nx,ny}, cnt+1 });
                chk[nx][ny] = 1;
            }
        }
    }
}

int move() {
    int num=0;
    for (int i = n - 2; i >= 0; i--) {
        for (int j = 0; j < m; j++) {
            arr[i + 1][j] = arr[i][j];
            if (arr[i + 1][j] == 1) {
                num++;
            }
        }
    }
    for (int i = 0; i < m; i++) {
        arr[0][i] = 0;
    }
    return num;
}

void go(int s,int cnt) {
    if (cnt == 3) {
        memcpy(arr, backup, sizeof(arr));
        int tmp = 0;
        while (1) {
            for (int i = 0; i < 3; i++) {
                shot(position[i]);
            }
            for (int i = 0; i < target.size(); i++) {
                int x = target[i].first;
                int y = target[i].second;
                if (arr[x][y] == 1) {
                    arr[x][y] = 0;
                    tmp++;
                }
            }
            target.clear();
            int num = move();
            if (num == 0) {
                break;
            }
        }
        if (tmp > ans)
            ans = tmp;
        return;
    }


    for (int i = s; i < m; i++) {
        position.push_back(i);
        go(i+1, cnt + 1);
        position.pop_back();
    }
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    
    cin >> n >> m >> d;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> arr[i][j];
            backup[i][j] = arr[i][j];
        }
    }
    go(0,0);
    cout << ans;
    return 0;
}


Written on April 8, 2019