Study hard
(c++)백준 14500번: 테트로미노 본문
https://www.acmicpc.net/problem/14500
14500번: 테트로미노
폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변�
www.acmicpc.net
[풀이]
브루트 포스 문제이므로 만들 수 있는 모든 테트로미노에 대해 그 합이 가장 최대인 수를 구하면 된다.
위와 같은 모양은 2차원 map에서 상하좌우 경로를 탐색하는 방법으로 쉽게 구할 수 있지만,
위와 같은 모양은 3칸까지 선택한 상황에서, 현재 칸의 상하좌우 칸을 검사했을 때 그 칸이 이미 선택된 경우 그 칸에 대해 상하좌우 칸을 다시 검색하여 만들 수 있다.
이렇게 4칸을 모두 선택했으면 선택된 칸들에 쓰인 수들의 합을 구해 최댓값을 갱신해나가면 된다.
#include <iostream>
#include <vector>
#include <algorithm>//max
using namespace std;
int N, M;
const int dx[] = { -1,1,0,0 };//좌, 우
const int dy[] = { 0,0,-1,1 };//상, 하
int Map[500][500];
bool check[500][500];
vector<pair<int, int>>v;
int Max = -1;
int getSum() {
int sum = 0;
for (int i = 0; i < 4; i++) {
int x = v[i].first;
int y = v[i].second;
sum += Map[x][y];
}
return sum;
}
//모든 경우의 테트로미노 확인
void getPos(int curx, int cury, int cnt) {
if (cnt == 4) {
int res = getSum();
Max = max(Max, res);
return;
}
for (int i = 0; i < 4; i++) {
int nx = curx + dx[i];
int ny = cury + dy[i];
if (nx < 0 || nx >= N || ny < 0 || ny >= M)
continue;
if (check[nx][ny] == false) {
check[nx][ny] = true;
v.push_back(make_pair(nx, ny));
getPos(nx, ny, cnt + 1);
v.pop_back();
check[nx][ny] = false;
}
//ㅗ모양일 때(다음 좌표가 이미 선택된 경우 그 좌표에서 다른 좌표 탐색하면 ㅗ모양 만들 수 있음)
else if (cnt==3) {
//nx, ny에 대해 상하좌우 확인
for (int j = 0; j < 4; j++) {
int nnx = nx + dx[j];
int nny = ny + dy[j];
if (nnx < 0 || nnx >= N || nny < 0 || nny >= M)
continue;
if (check[nnx][nny] == false) {
check[nnx][nny] = true;
v.push_back(make_pair(nnx, nny));
getPos(nnx, nny, cnt + 1);
v.pop_back();
check[nnx][nny] = false;
}
}
}
}
}
void solution() {
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++) {
check[i][j] = true;
v.push_back(make_pair(i, j));
getPos(i, j, 1);
v.pop_back();
check[i][j] = false;
}
}
cout << Max << '\n';
}
int main() {
solution();
return 0;
}
'백준 > 브루트 포스' 카테고리의 다른 글
(c++)백준 1987번: 알파벳 (0) | 2020.08.28 |
---|---|
(c++)백준 16198번: 에너지 모으기 (0) | 2020.08.26 |
(c++)백준 15658번: 연산자 끼워넣기 (2) (0) | 2020.08.13 |
(c++)백준 14888번: 연산자 끼워넣기 (0) | 2020.08.13 |
(c++)백준 14225번: 부분수열의 합 (0) | 2020.08.11 |