반응형
[문과 코린이의 IT 기록장] C++ 백준 문제풀이[BF] - 테트로미노 (14500)
[ 문제 ]
폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다.
- 정사각형은 서로 겹치면 안 된다.
- 도형은 모두 연결되어 있어야 한다.
- 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다.
정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다.
아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누어져 있으며, 각각의 칸에는 정수가 하나 쓰여 있다.
테트로미노 하나를 적절히 놓아서 테트로미노가 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성하시오.
테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야 하며, 회전이나 대칭을 시켜도 된다.
[ 입력 ]
첫째 줄에 종이의 세로 크기 N과 가로 크기 M이 주어진다. (4 ≤ N, M ≤ 500)
둘째 줄부터 N개의 줄에 종이에 쓰여 있는 수가 주어진다. i번째 줄의 j번째 수는 위에서부터 i번째 칸, 왼쪽에서부터 j번째 칸에 쓰여 있는 수이다. 입력으로 주어지는 수는 1,000을 넘지 않는 자연수이다.
[ 출력 ]
첫째 줄에 테트로미노가 놓인 칸에 쓰인 수들의 합의 최댓값을 출력한다.
[ 코드 ]
#include<iostream>
using namespace std;
int a[500][500];
int main() {
int n, m;
cin >> n >> m;
// nxm배열에 값 넣기
for (int i = 0; i < n; i++)
{
for (int k = 0; k < m; k++)
{
cin >> a[i][k];
}
}
/* 19가지의 경우의 수 시작 */
int ans = 0;
for (int i = 0; i < n; i++) // i는 n 세로
{
for (int j = 0; j < m; j++) // j는 m 가로
{
// 1-1 O
if (j+3 < m)
{
int temp = a[i][j] + a[i][j + 1] + a[i][j + 2] + a[i][j + 3];
if (ans < temp) // 최대값 구하기
{
ans = temp;
}
}
// 1-2 O
if (i + 3 < n)
{
int temp = a[i][j] + a[i + 1][j] + a[i + 2][j] + a[i + 3][j];
if (ans < temp)
{
ans = temp;
}
}
// 3-3.
if (i + 1 < n && j + 2 < m)
{
int temp = a[i][j] + a[i + 1][j] + a[i + 1][j + 1] + a[i + 1][j + 2];
if (ans < temp)
{
ans = temp;
}
}
// 3-4.
if (i + 2 < n && j + 1 < m)
{
int temp = a[i][j] + a[i][j + 1] + a[i + 1][j] + a[i + 2][j];
if (ans < temp)
{
ans = temp;
}
}
// 3-1.
if (i + 1 < n && j + 2 < m)
{
int temp = a[i][j] + a[i][j + 1] + a[i][j + 2] + a[i + 1][j + 2];
if (ans < temp)
{
ans = temp;
}
}
// 3-2.
if (i + 2 < n && j - 1 >= 0)
{
int temp = a[i][j] + a[i + 1][j] + a[i + 2][j] + a[i + 2][j - 1];
if (ans < temp)
{
ans = temp;
}
}
// 3-5.
if (i - 1 >= 0 && j + 2 < m)
{
int temp = a[i][j] + a[i][j + 1] + a[i][j + 2] + a[i - 1][j + 2];
if (ans < temp)
{
ans = temp;
}
}
// 3-6.
if (i + 2 < n && j + 1 < m)
{
int temp = a[i][j] + a[i + 1][j] + a[i + 2][j] + a[i + 2][j + 1];
if (ans < temp)
{
ans = temp;
}
}
// 3-7.
if (i + 1 < n && j + 1 < m)
{
int temp = a[i][j] + a[i][j + 1] + a[i][j + 2] + a[i + 1][j];
if (ans < temp)
{
ans = temp;
}
}
// 3-8.
if (i + 2 < n && j + 1 < m)
{
int temp = a[i][j] + a[i][j + 1] + a[i + 1][j + 1] + a[i + 2][j + 1];
if (ans < temp)
{
ans = temp;
}
}
// 2-1.
if (i + 1 < n && j + 1 < m)
{
int temp = a[i][j] + a[i][j + 1] + a[i + 1][j] + a[i + 1][j + 1];
if (ans < temp)
{
ans = temp;
}
}
// 4-3.
if (i - 1 >= 0 && j + 2 < m)
{
int temp = a[i][j] + a[i][j + 1] + a[i - 1][j + 1] + a[i - 1][j + 2];
if (ans < temp)
{
ans = temp;
}
}
// 4-4.
if (i + 2 < n && j + 1 < m)
{
int temp = a[i][j] + a[i + 1][j] + a[i + 1][j + 1] + a[i + 2][j + 1];
if (ans < temp)
{
ans = temp;
}
}
// 4-1.
if (i + 1 < n && j + 2 < m)
{
int temp = a[i][j] + a[i][j + 1] + a[i + 1][j + 1] + a[i + 1][j + 2];
if (ans < temp)
{
ans = temp;
}
}
// 4-2.
if (i + 2 < n && j - 1 >= 0)
{
int temp = a[i][j] + a[i + 1][j] + a[i + 1][j - 1] + a[i + 2][j - 1];
if (ans < temp)
{
ans = temp;
}
}
// 5-3, 5-4
if (j + 2 < m)
{
int temp = a[i][j] + a[i][j + 1] + a[i][j + 2];
if (i - 1 >= 0) // 5-4
{
int temp1 = temp + a[i - 1][j + 1];
if (ans < temp1)
{
ans = temp1;
}
}
if (i + 1 < n) // 5-3
{
int temp1 = temp + a[i + 1][j + 1];
if (ans < temp1)
{
ans = temp1;
}
}
}
// 5-1, 5-2
if (i + 2 < n)
{
int temp = a[i][j] + a[i + 1][j] + a[i + 2][j];
if (j + 1 < m) // 5-1
{
int temp1 = temp + a[i + 1][j + 1];
if (ans < temp1)
{
ans = temp1;
}
}
if (j - 1 >= 0) // 5-2
{
int temp1 = temp + a[i + 1][j - 1];
if (ans < temp1)
{
ans = temp1;
}
}
}
}
}
cout << ans << '\n';
return 0;
}
반응형
'문과 코린이의, [C. C++] 기록 > C++ 백준 문제풀이' 카테고리의 다른 글
[문과 코린이의 IT 기록장] C++ 백준 문제풀이[BF] - 수 이어쓰기 1 (1748) (0) | 2021.08.14 |
---|---|
[문과 코린이의 IT 기록장] C++ 백준 문제풀이[BF] - 카잉 달력 (6064) (0) | 2021.08.10 |
[문과 코린이의 IT 기록장] C++ 백준 문제풀이 - 리모컨 (1107) (0) | 2021.08.08 |
[문과 코린이의 IT 기록장] C++ 백준 문제풀이 - 날짜 계산 (1476) (0) | 2021.08.08 |
[문과 코린이의 IT 기록장] C++ 백준 문제풀이 - 사탕 게임 (3085) (0) | 2021.08.08 |