[백준 14500] 테트로미노(C++)

2022. 9. 14. 17:32· CodingTest/Baekjoon
목차
  1. 🔎문제해석
  2. 💻코드
  3. ✔느낀 점

📕문제


폴리오미노란 크기가 1 ×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다.

  • 정사각형은 서로 겹치면 안 된다.
  • 도형은 모두 연결되어 있어야 한다.
  • 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다.

정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다.

아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1 ×1 크기의 칸으로 나누어져 있으며, 각각의 칸에는 정수가 하나 쓰여 있다.

테트로미노 하나를 적절히 놓아서 테트로미노가 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성하시오.

테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야 하며, 회전이나 대칭을 시켜도 된다.

📕입력


첫째 줄에 종이의 세로 크기 N과 가로 크기 M이 주어진다. (4 ≤ N, M ≤ 500)

둘째 줄부터 N개의 줄에 종이에 쓰여 있는 수가 주어진다. i번째 줄의 j번째 수는 위에서부터 i번째 칸, 왼쪽에서부터 j번째 칸에 쓰여 있는 수이다. 입력으로 주어지는 수는 1,000을 넘지 않는 자연수이다.

📕출력


첫째 줄에 테트로미노가 놓인 칸에 쓰인 수들의 합의 최댓값을 출력한다.

 

🔎문제해석


나는 모든 경우의 수를 구해서 문제를 해결했지만, 문제를 다 풀고 다른 사람들은 어떻게 풀었는지 궁금해서 구글링을 해봤는데 dfs 등 탐색으로 푸는 풀이를 보고 아직 멀었구나 라는 것을 느꼈다..ㅠ나는 모든 좌표에 대해서 만들 수 있는 도형의 경우의 수를 대입해서 최댓값을 구했다.
if문을 덕지덕지 사용했지만, 생각해보면 if문 수를 덜 쓰고도 풀 수 있을 것 같긴 하다. 내가 못해서 그럼.

 

아래 그림은 테트로미노의 5가지 모양이다. 이 모양을 대칭, 회전을 시켜도 상관없다.

 

💡1번 도형으로 만들 수 있는 도형의 종류는 2가지다.

세로로 4개를 이어 붙인 모양과 가로로 4개를 이어 붙인 모양이다.

 

💡2번 도형으로 만들 수 있는 도형의 종류는 1가지다.

💡3번 도형으로 만들 수 있는 도형의 종류는 8가지다.

근데 여기서 만들수 있는 모양과 5번을 살짝 겹쳐서 본다면 툭 뒤 나온 부분을 조금만 수정하면 5번의 모양을 만들어낼 수 있다는 사실을 알 수 있다. 그러한 것을 반복문을 통해서 나는 5번과 3번을 같이 묶어서 처리했다.

 

💡4번 도형으로 만들 수 있는 도형의 종류는 4가지다.

각 종류마다 예외처리를 해서 4개의 경우의 수를 구했다.

 

이렇게 한 좌표에 대해서 모든 도형의 값을 구했고, 그것을 모든 좌표로 확대하면 N * M 행렬에 대해서  테트로미노로 구할 수 있는 최댓값을 구할 수 있다.


💻코드

/*
백준 골드4 테트로미노
사각형의 형태는 5개고 회전,대칭 가능
*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n,m,sum=0,big=0;
vector<vector<int>>graph;
int main(){
cin>>n>>m;
graph.resize(n,vector<int>(m,0));
for(int i=0; i<n;i++){
for(int j=0; j<m;j++){
cin>>graph[i][j];
}
}
//모든 칸에 대해서 만들 수 있는 모든 사각형을 넣어보기?
for(int i=0; i<n;i++){
for(int j=0; j<m;j++){
//항상 graph[i][j]가 있어야함.
if(i+3<n){ //세로로 4개 이어붙인거
sum=graph[i][j]+graph[i+1][j]+graph[i+2][j]+graph[i+3][j];
if(sum>big){
big=sum;
}
}
if(j+3<m){ //가로로 4개 이어붙인거
sum=graph[i][j]+graph[i][j+1]+graph[i][j+2]+graph[i][j+3];
if(sum>big){
big=sum;
}
}
if(i+1<n && j+1<m){ //2*2 정사각형
sum=graph[i][j]+graph[i+1][j]+graph[i][j+1]+graph[i+1][j+1];
if(sum>big){
big=sum;
}
}
if(i+2<n&& j+1<m){ //세로로 3개 이어 붙이고 가로로 오른쪽 하나씩 이어붙일 경우
for(int k=0;k<3;k++){
if(sum<graph[i][j]+graph[i+1][j]+graph[i+2][j]+graph[i+k][j+1])
{
sum=graph[i][j]+graph[i+1][j]+graph[i+2][j]+graph[i+k][j+1];
}
}
if(sum>big){
big=sum;
}
}
if(i+2<n && j-1>=0){ //세로로 3개 이어붙이고 가로 왼쪽에 하나 붙이기.
for(int k=0; k<3; k++){
if(sum<graph[i][j]+graph[i+1][j]+graph[i+2][j]+graph[i+k][j-1])
{
sum=graph[i][j]+graph[i+1][j]+graph[i+2][j]+graph[i+k][j-1];
}
}
if(sum>big){
big=sum;
}
}
if(j+2<m && i+1<n){ //가로로 3개 이어붙이고 아래로 세로 1개 붙이는 경우.
for(int k=0; k<3;k++){
if(sum<graph[i][j]+graph[i][j+1]+graph[i][j+2]+graph[i+1][j+k])
{
sum=graph[i][j]+graph[i][j+1]+graph[i][j+2]+graph[i+1][j+k];
}
}
if(sum>big){
big=sum;
}
}
if(j+2<m && i-1>=0){ //가로로 3개 이어붙이고 아래로 세로 1개 붙이는 경우.
for(int k=0; k<3;k++){
if(sum<graph[i][j]+graph[i][j+1]+graph[i][j+2]+graph[i-1][j+k])
{
sum=graph[i][j]+graph[i][j+1]+graph[i][j+2]+graph[i-1][j+k];
}
}
if(sum>big){
big=sum;
}
}
//엇갈려서 2개 붙이는 경우. 총 4가지의 모형이 발견됨.
if(i+2<n &&j+1<m)
{
sum=graph[i][j]+graph[i+1][j]+graph[i+1][j+1]+graph[i+2][j+1];
if(sum>big){
big=sum;
}
}
if(i+1<n && j-1 >=0 && j+1<m)
{
sum=graph[i][j]+graph[i][j+1]+graph[i+1][j-1]+graph[i+1][j];
if(sum>big){
big=sum;
}
}
if(j-1>=0 && i+1 <n && j+1<m)
{
sum=graph[i][j]+graph[i][j-1]+graph[i+1][j]+graph[i+1][j+1];
if(sum>big){
big=sum;
}
}
if(i-1>=0 && j+1<m && i+1 <n){
sum=graph[i][j]+graph[i+1][j]+graph[i][j+1]+graph[i-1][j+1];
if(sum>big){
big=sum;
}
}
}
}
cout<<big; //최대값 출력.
}

✔느낀 점

  • 그냥 단순한 구현 문제로 생각해서 풀었기에 쉬웠다. 
  • DFS를 사용한 풀이가 있다는 것이 충격이었다.
저작자표시 (새창열림)

'CodingTest > Baekjoon' 카테고리의 다른 글

[백준 6986] 절사평균(C++)  (0) 2022.09.17
[백준 20057] 마법사 상어와 토네이도(C++)  (0) 2022.09.15
[백준 18111] 마인크래프트(C++)  (2) 2022.09.13
[백준 2281] 데스노트(C++)  (0) 2022.09.08
[백준 2156] 포도주 시식(C++)  (0) 2022.09.06
  1. 🔎문제해석
  2. 💻코드
  3. ✔느낀 점
'CodingTest/Baekjoon' 카테고리의 다른 글
  • [백준 6986] 절사평균(C++)
  • [백준 20057] 마법사 상어와 토네이도(C++)
  • [백준 18111] 마인크래프트(C++)
  • [백준 2281] 데스노트(C++)
재한
재한
안녕하세요 💻
재한
짜이한
전체
오늘
어제
  • 분류 전체보기 (502)
    • Skils (116)
      • Android (50)
      • C++ (5)
      • Kotlin (36)
      • Algorithm (24)
      • Server (1)
    • CodingTest (228)
      • Programmers (45)
      • Baekjoon (183)
    • Experience (8)
      • 후기(코딩테스트,프로그램,프로젝트) (8)
    • Computer Science (70)
      • Design Pattern (2)
      • OOP (2)
      • Computer Architecture (14)
      • OS (2)
      • Software Engineering (3)
      • DataBase (8)
      • Network (39)
    • 학교 (75)
      • R프로그래밍 (26)
      • 회계와 사회생활 (17)
      • 컴퓨터학개론 (20)
      • it기술경영개론 (12)

블로그 메뉴

  • 홈
  • 태그
  • 카테고리
  • 글쓰기
  • 설정

인기 글

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
재한
[백준 14500] 테트로미노(C++)
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.