PS
백준 17085번 십자가 2개 놓기
남마허
2020. 3. 18. 10:54
https://www.acmicpc.net/problem/17085
17085번: 십자가 2개 놓기
첫째 줄에 격자판의 크기 N, M (2 ≤ N, M ≤ 15)이 주어진다. 둘째 줄부터 N개의 줄에 격자판의 상태가 주어진다. 항상 두 개의 십자가를 놓을 수 있는 경우만 입력으로 주어진다.
www.acmicpc.net
<접근방법>
완전 탐색문제 입니다.
7 7
...#...
...#...
...#...
#######
...####
...#.#.
...#...
이 테스트 케이스의 경우, 5*5로 답이 25입니다.
두 점이 선택되었을 때, 십자가 길이를 하나 하나 바꿔가면서 최대값을 찾아야 합니다.
<느낀 점>
구현이 조금 까다로운 문제입니다.
<코드>
#include <iostream>
#include <algorithm>
using namespace std;
int n, m, res;
char map[20][20];
bool range_check(int y, int x, int r) {
for (int i = -1; i <= 1; i+=2) {
int ty = y + r * i;
int tx = x + r * i;
if (ty < 0 || ty >= n || tx < 0 || tx >= m) return false;
}
return true;
}
int other() {
int tmp2 = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == '.') continue;
int k = 1;
while (range_check(i, j, k) &&
map[i + k][j] == '#' && map[i][j + k] == '#' &&
map[i - k][j] == '#' && map[i][j - k] == '#') {
k++;
}
tmp2 = max(tmp2, (k-1) * 4 + 1);
}
}
return tmp2;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> map[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == '.') continue;
int k = 0;
while (range_check(i, j, k) &&
map[i + k][j] == '#' && map[i][j + k] == '#' &&
map[i - k][j] == '#' && map[i][j - k] == '#') {
map[i + k][j] = map[i][j + k] = map[i - k][j] = map[i][j - k] = '.';
int tmp1 = 1 + k * 4;
int tmp2 = other();
res = max(res, tmp1 * tmp2);
k++;
}
for (int l = 0; l < k; l++) {
map[i + l][j] = map[i][j + l] = map[i - l][j] = map[i][j - l] = '#';
}
}
}
cout << res << '\n';
return 0;
}
반응형