14500 테트로미노
14500 테트로미노 (c++)
문제
https://www.acmicpc.net/problem/14500
접근 방식
브루트포스, 도형
- 테트리스 도형들의 몇가지 공통점을 찾았다.
- 2*3 도형에서 2개를 빼서 만들어지는 도형
- 3*2 도형에서 2개를 빼서 만들어지는 도형
- 2*2 도형
- 1*4 도형
- 4*1 도형
- 여기서 핵심은 23과 32를 미리 구해놓고 각각 2개씩 빼가면서 최대값을 비교한다는 것이다.
- 불필요한 덧셈을 줄일 수 있었다.
문제 풀이
#include <iostream>
using namespace std;
inline short Max(short a, short b) { return a > b ? a : b; }
short N, M;
short arr[500][500];
short totalMax = 0;
void Func(short y, short x)
{
short curMax = 0, sum;
// 1) 2 * 3
if (y + 1 < N && x + 2 < M)
{
sum = arr[y][x] + arr[y][x + 1] + arr[y][x + 2] + arr[y + 1][x] + arr[y + 1][x + 1] + arr[y + 1][x + 2];
// 1) 01
curMax = Max(curMax, sum - arr[y][x] - arr[y][x + 1]);
// 2) 12
curMax = Max(curMax, sum - arr[y][x + 1] - arr[y][x + 2]);
// 3) 34
curMax = Max(curMax, sum - arr[y + 1][x] - arr[y + 1][x + 1]);
// 4) 45
curMax = Max(curMax, sum - arr[y + 1][x + 1] - arr[y + 1][x + 2]);
// 5) 05
curMax = Max(curMax, sum - arr[y][x] - arr[y + 1][x + 2]);
// 6) 23
curMax = Max(curMax, sum - arr[y][x + 2] - arr[y + 1][x]);
// 7) 02
curMax = Max(curMax, sum - arr[y][x] - arr[y][x + 2]);
// 8) 35
curMax = Max(curMax, sum - arr[y + 1][x] - arr[y + 1][x + 2]);
}
// 2) 3 * 2
if (y + 2 < N && x + 1 < M)
{
sum = arr[y][x] + arr[y + 1][x] + arr[y + 2][x] + arr[y][x + 1] + arr[y + 1][x + 1] + arr[y + 2][x + 1];
// 1) 02
curMax = Max(curMax, sum - arr[y][x] - arr[y + 1][x]);
// 2) 24
curMax = Max(curMax, sum - arr[y + 1][x] - arr[y + 2][x]);
// 3) 13
curMax = Max(curMax, sum - arr[y][x + 1] - arr[y + 1][x + 1]);
// 4) 35
curMax = Max(curMax, sum - arr[y + 1][x + 1] - arr[y + 2][x + 1]);
// 5) 05
curMax = Max(curMax, sum - arr[y][x] - arr[y + 2][x + 1]);
// 6) 14
curMax = Max(curMax, sum - arr[y][x + 1] - arr[y + 2][x]);
// 7) 04
curMax = Max(curMax, sum - arr[y][x] - arr[y + 2][x]);
// 8) 15
curMax = Max(curMax, sum - arr[y][x + 1] - arr[y + 2][x + 1]);
}
// 3) 2 * 2
if (y + 1 < N && x + 1 < M)
{
sum = arr[y][x] + arr[y][x + 1] + arr[y + 1][x] + arr[y + 1][x + 1];
curMax = Max(curMax, sum);
}
// 4) 1 * 4
if (y + 3 < N)
{
sum = arr[y][x] + arr[y + 1][x] + arr[y + 2][x] + arr[y + 3][x];
curMax = Max(curMax, sum);
}
if (x + 3 < M)
{
sum = arr[y][x] + arr[y][x + 1] + arr[y][x + 2] + arr[y][x + 3];
curMax = Max(curMax, sum);
}
totalMax = Max(curMax, totalMax);
}
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> N >> M;
for (short i = 0; i < N; ++i)
{
for (short j = 0; j < M; ++j)
{
cin >> arr[i][j];
}
}
for (short i = 0; i < N; ++i)
{
for (short j = 0; j < M; ++j)
{
Func(i, j);
}
}
cout << totalMax << "\n";
return 0;
}
다시 생각해볼 점
- 도형의 칸수가 적기 때문에 for문을 돌리지 않고 직접 더하고 빼는게 효율적이라 생각했다.
- inline Max 함수를 만들어 사용함으로써 시간을 줄였다.
- 23, 32 도형의 공통점을 찾아서 연산 시간을 줄였다.
- 어떻게 자르던 4칸짜리 도형이고, 한 칸에 1’000을 넘지 않기 때문에 최대값이 4’000 이라 자료형을 int 에서 short 로 줄였더니 메모리 사용량과 시간이 현저하게 줄었다.
- 무려 7등에 안착했다. 10등 이내는 처음인 것 같다.
- 앞으로 문제에 맞는 적절한 자료형을 사용하는데에 더 주의를 기울여야겠다.