문제 풀이

 

 문제 해결을 위한 절차는 다음과 같습니다.

1) 궁수의 위치를 정하여 simulation 함수로 넘겨줍니다.

2) 궁수마다 가장 가까운 적의 위치를 중복없이 저장해 줍니다.

3) 사정 거리 내에 들어온다면 적을 없애주고, 적을 한 칸 전진 시킵니다.

4) 남아있는 적이 없다면 simulation을 종료시키고 물리친 적이 가장 많을 때를 저장시켜 줍니다.

 

 

코드

 

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <cstring>
 
using namespace std;
 
int n, m, d;
int field[15][15];
 
int dist(int ex, int ey, int ay) {
    return abs(n - ex) + abs(ey - ay);
}
 
int simulation(int a, int b, int c) {
    
    int sum = 0;
    int tmp[15][15];
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            tmp[i][j] = field[i][j];
        }
    }
 
    while (1) {
        vector<int> v = { a, b, c };
        set<pair<intint>> s;
 
        for (auto x : v) { //x = a
            
            int dist_f[15][15];
            int dist_min = -1;
 
            memset(dist_f, -1sizeof(dist_f));
 
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    
                    if (tmp[i][j] == 1) {
                        dist_f[i][j] = dist(i, j, x);
                        if (dist_min == -1 || dist_min > dist_f[i][j]) {
                            dist_min = dist_f[i][j];
                        }
                    }
                }
            }
 
            if (dist_min <= d) {
 
                int ex = -1, ey = -1;
                for (int j = 0; j < m; j++) {
                    for (int i = 0; i < n; i++) {
                        if (dist_min == dist_f[i][j]) {
                            ex = i;
                            ey = j;
                            break;
                        }
                    }
                    if (ey != -1) {
                        break;
                    }
                }
                s.emplace(ex, ey);
            }
        }
        
        for (auto x : s) {
            tmp[x.first][x.second] = 0;
            sum++;
        }
        
        bool isFin = true;
        for (int i = n - 1; i >= 0; i--) {
            for (int j = 0; j < m; j++) {
                if(i == 0){
                    tmp[i][j] = 0;
                }
                else{
                    tmp[i][j] = tmp[i - 1][j];
                }
                
                if (tmp[i][j] == 1) {
                    isFin = false;
                }
            }
        }
        if (isFin) return sum;
    }
}
 
int main() {
 
    cin >> n >> m >> d;
 
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> field[i][j];
        }
    }
 
    vector<int> p(m, 0);
    p[0= 1;
    p[1= 1;
    p[2= 1;
 
    sort(p.begin(), p.end());
 
    int ans = -1;
    do{
        vector<int> v;
 
        for (int i = 0; i < m; i++) {
            if (p[i] == 1) {
                v.push_back(i);
            }
        }
        int sum = simulation(v[0], v[1], v[2]);
 
        if (ans == -1 || sum > ans) {
            ans = sum;
        }
 
    } while (next_permutation(p.begin(), p.end()));
 
    cout << ans << '\n';
 
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter

 

 

제출 결과

 

 

 

문제 출처

 

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

 

17135번: 캐슬 디펜스

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

www.acmicpc.net

 

+ Recent posts