습관처럼

백준 14500 - 테트로미노 본문

Algorithms/BOJ

백준 14500 - 테트로미노

dev.wookii 2020. 3. 3. 21:17

https://www.acmicpc.net/problem/14500

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다. 정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다. 아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누

www.acmicpc.net

문제 설명


아래의 그림처럼 4개의 정사각형이 연결되어(면이 닿아있다는 의미)있다면, 이 3개의 도형을 테트로미노라고 부른다. 이때 N*M의 메트릭스가 주어질때(각각의 메트릭스에는 하나의 작은 정사각형마다 숫자 크기가 적혀있다), 테트로미노 안의 숫자의 합이 가장 큰 숫자가 되게 하는 값을 구하는 문제이다~

 

접근 방식

 


일단 정말 완전탐색에 의미에 입각해서 모든 도형을 회전시킬 수 있는 모든방향으로 회전시킨 모형과,

대칭시킬 수 있는 모든 방향으로 대칭시킨 모형을 하나하나 다 대입해서 풀어도 답이 나온다고 한다.

저는 처음에 위에 말했던 방식으로 진행했다가 실패하고 다른 방법을 참고했습니다.

하지만, 모형들을 잘보면 공통점을 하나 발견할 수 있다.

바로 Depth = 3 이라는 것이다(***)

Depth가 나왔다는 건  DFS로의 접근이 가능하다!!!!

 

 

 

코드


#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

const int MAX = 501;

int n,m;
int mat[MAX][MAX];
bool visit[MAX][MAX];

typedef struct{
    int y,x;
}Dir;

Dir moveDir[4]={{1,0},{-1,0},{0,1},{0,-1}};

int dfs(int y,int x,int cnt){	//DFS
    if(cnt==4){	//Depth==4가 되면 stop
        return mat[y][x];
    }
    int sum=0;
    for(int i=0;i<4;i++){
        int ny = y+ moveDir[i].y;
        int nx = x +moveDir[i].x;
        if(0<=ny&& ny<n&& 0<=nx&&nx<m && !visit[ny][nx]){
            visit[ny][nx]=true;
            sum=max(sum,mat[y][x]+ dfs(ny,nx,cnt+1));
            visit[ny][nx]=false;
        }
    }
    return sum;
}
int fxxx(int y, int x){
    int result = 0;
    //ㅗ 좌표의 중심을 가운데로 설정한다.
    if (y >= 1 && x >= 1 && x < m-1)
        result = max(result, mat[y][x-1]+mat[y][x]+mat[y-1][x]+mat[y][x+1]);
    //ㅏ 
    if (y >= 1 && y<n-1 && x<m-1)
        result = max(result, mat[y-1][x]+mat[y][x]+mat[y][x+1]+mat[y+1][x]);
    //ㅜ
    if (y >= 0 && y < n-1 && x <m-1)
        result = max(result, mat[y][x-1]+mat[y][x]+mat[y+1][x]+mat[y][x+1]);
    //ㅓ 
    if (y >= 1 && y <n-1 && x>= 1)
        result = max(result, mat[y-1][x]+mat[y][x]+mat[y][x-1]+mat[y+1][x]);
    return result;
}
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>mat[i][j];
        }
    }
    int ans=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            visit[i][j]=true;
            ans=max(ans,dfs(i,j,1));
            ans=max(ans,fxxx(i,j));
            visit[i][j]=false;
        }
    }
    cout<<ans<<"\n";
    return 0;
}

 

funny algorithm~:0

'Algorithms > BOJ' 카테고리의 다른 글

백준 17144 - 미세먼지 안녕!  (0) 2020.03.05
백준 16236 - 아기상어  (0) 2020.03.04
백준 1504 - 특정한 최단 경로  (0) 2020.02.20
백준 1916 - 최소비용 구하기  (0) 2020.02.18
백준 1018 - 체스판 다시 칠하기  (0) 2020.02.10