문제 보기
https://www.acmicpc.net/problem/14500
문제
입력
출력
시간 제한 | 메모리 제한 |
2 초 | 512 MB |
풀이방법
문제를 이해하는 것이 조금 어려운데
2차원 배열 위에 테트리스 조각을 놓아,
테트리스 조각이 놓인 곳의 숫자들의 합기 최대가 되도록 만드는 문제이다.
예제 1을 확인해 보자
예제 입력 1
5 5
1 2 3 4 5
5 4 3 2 1
2 3 4 5 6
6 5 4 3 2
1 2 1 2 1
예제 출력 1
19
어디에 테트리스 조각을 놓았길래 19가 나왔을까?
4 + 4 + 5 + 6 = 19
해당 위치에 ㄱ자가 반전 된 모양의 조각을 넣었더니 출력값을 확인할 수 있었다.
그럼 문제를 이해하였으니 본격적으로 풀이 방법에 대해 알아보자.
나는 대학생 시절 C# 소켓통신을 사용한 멀티 테트리스를 만들어 본 경험이 있어서
쉽게 풀이 방법을 유추할 수 있었다.
공개하기 부끄러우나 혹시 관심이 있다면 아래 링크에서 확인할 수 있다.
https://github.com/MetroDefro/TetrisProject
그렇게 유추한 것이 무엇이냐면?
일단 테트리스 조각들을 어떻게 표현할 것인가이다.
구현 방법은 아래와 같다.
우선 byte 3차원 배열을 사용하였고
19개의 테트리스 조각을 4x4 배열(테트리스 조각이 잡아먹을 수 있는 최대 칸 수 고려) 안에 그려 넣었다.
byte[,,] tetris = {
{ {1, 1, 0, 0 },
{1, 1, 0, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 1, 1 },
{0, 0, 0, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 0, 0, 0 },
{1, 0, 0, 0 },
{1, 0, 0, 0 },
{1, 0, 0, 0 } } ,
{ {1, 0, 0, 0 },
{1, 0, 0, 0 },
{1, 1, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 0, 1, 0 },
{1, 1, 1, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 0, 0 },
{0, 1, 0, 0 },
{0, 1, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 1, 0 },
{1, 0, 0, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 1, 0, 0 },
{0, 1, 0, 0 },
{1, 1, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 1, 0 },
{0, 0, 1, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 0, 0 },
{1, 0, 0, 0 },
{1, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 0, 0, 0 },
{1, 1, 1, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 0, 0, 0 },
{1, 1, 0, 0 },
{0, 1, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 1, 1, 0 },
{1, 1, 0, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 1, 0, 0 },
{1, 1, 0, 0 },
{1, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 0, 0 },
{0, 1, 1, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 1, 0, 0 },
{1, 1, 1, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 1, 0, 0 },
{1, 1, 0, 0 },
{0, 1, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 1, 0 },
{0, 1, 0, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 0, 0, 0 },
{1, 1, 0, 0 },
{1, 0, 0, 0 },
{0, 0, 0, 0 } } ,
};
bool 배열로도 구현 가능하겠지만...
byte 배열을 사용한 이유는 0과 1로 나타내는 것이 가시성 있다고 판단하였기 때문.
이제 M x N 배열을 순회하며
모든 조각을 대조하고 max 값을 갱신하면 끝이다.
int max = 0;
// M x N 배열 순회
for(int m = 0; m < M; m++)
{
for(int n = 0; n < N; n++)
{
// 모든 조각 순회
for (int i = 0; i < 19; i++)
{
// max값 갱신
max = Math.Max(max, Sum(i, m, n));
}
}
}
// 조각 안의 숫자를 더하는 메서드
int Sum(int index, int m, int n)
{
int sum = 0;
for (int x = 0; x < 4; x++)
{
for (int y = 0; y < 4; y++)
{
// 조각의 해당 위치에 블럭이 없으면 continue
if (tetris[index, x, y] == 0)
continue;
// 조각이 M x N 배열의 범위를 넘어갔으면 0을 리턴한다.
if (m + x >= M || n + y >= N)
return 0;
// M x N 배열의 해당 위치에 있는 숫자를 더한다.
sum += arr[m + x, n + y];
}
}
return sum;
}
전체 코드
더보기
using System;
namespace BackjoonCodingTest
{
internal class Program
{
static void Main(string[] args)
{
using var reader = new System.IO.StreamReader(Console.OpenStandardInput());
using var print = new System.IO.StreamWriter(Console.OpenStandardOutput());
string[] inputs = reader.ReadLine().Split();
int N = int.Parse(inputs[0]);
int M = int.Parse(inputs[1]);
short[,] arr = new short[M, N];
for(int i = 0; i < N; i++)
{
inputs = reader.ReadLine().Split();
for(int j = 0; j < M; j++)
{
arr[j, i] = short.Parse(inputs[j]);
}
}
byte[,,] tetris = {
{ {1, 1, 0, 0 },
{1, 1, 0, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 1, 1 },
{0, 0, 0, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 0, 0, 0 },
{1, 0, 0, 0 },
{1, 0, 0, 0 },
{1, 0, 0, 0 } } ,
{ {1, 0, 0, 0 },
{1, 0, 0, 0 },
{1, 1, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 0, 1, 0 },
{1, 1, 1, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 0, 0 },
{0, 1, 0, 0 },
{0, 1, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 1, 0 },
{1, 0, 0, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 1, 0, 0 },
{0, 1, 0, 0 },
{1, 1, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 1, 0 },
{0, 0, 1, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 0, 0 },
{1, 0, 0, 0 },
{1, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 0, 0, 0 },
{1, 1, 1, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 0, 0, 0 },
{1, 1, 0, 0 },
{0, 1, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 1, 1, 0 },
{1, 1, 0, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 1, 0, 0 },
{1, 1, 0, 0 },
{1, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 0, 0 },
{0, 1, 1, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 1, 0, 0 },
{1, 1, 1, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {0, 1, 0, 0 },
{1, 1, 0, 0 },
{0, 1, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 1, 1, 0 },
{0, 1, 0, 0 },
{0, 0, 0, 0 },
{0, 0, 0, 0 } } ,
{ {1, 0, 0, 0 },
{1, 1, 0, 0 },
{1, 0, 0, 0 },
{0, 0, 0, 0 } } ,
};
int max = 0;
for(int m = 0; m < M; m++)
{
for(int n = 0; n < N; n++)
{
for (int i = 0; i < 19; i++)
{
max = Math.Max(max, Sum(i, m, n));
}
}
}
print.WriteLine(max);
int Sum(int index, int m, int n)
{
int sum = 0;
for (int x = 0; x < 4; x++)
{
for (int y = 0; y < 4; y++)
{
if (tetris[index, x, y] == 0)
continue;
if (m + x >= M || n + y >= N)
return 0;
sum += arr[m + x, n + y];
}
}
return sum;
}
reader.Close();
print.Close();
}
}
}
'ProblemSolve' 카테고리의 다른 글
[백준][C#] 1753 최단경로 - 골드4 (0) | 2023.07.12 |
---|---|
[백준][C#] 1504 특정한 최단 경로 - 골드4 (0) | 2023.07.12 |
[백준][C#] 2293 동전 1 - 골드5 (1) | 2023.07.07 |
[백준][C#] 1330 두 수 비교하기 - 브론즈5 (0) | 2023.07.07 |
[백준][C#] 14503 로봇 청소기 - 골드5 (0) | 2023.07.07 |