본문 바로가기

백준

백준14500 - 테트로미노

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

 

14500번: 테트로미노

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

www.acmicpc.net

처음에 만만하게 봐서 bfs를 이용하여 풀었는데 생각해보니 ㅗ모양은 bfs로 찾을 수 없어서 애먹었던 문제다. 또한 4개짜리 조각을 찾으면 찾았던 길을 거슬러와서 다시 미방문처리도 해야된다. 여러모로 생각할 것이 많았던 좋은 문제다.

 

#include <iostream>
#include <stack>
#include <string.h>
#include <algorithm>
#define MAX 501
using namespace std;

class Point {
public:
	int x, y, z, k; //x와 y는 위치, z는 지금까지 먹은 칸의 갯수, k는 점수
	Point(int x, int y, int z, int k) {
		this->x = x;
		this->y = y;
		this->z = z; 
		this->k = k;
	}
};

int mat[MAX][MAX]; //좌표 정보
bool visit[MAX][MAX]; //방문 여부
int N, M;

//상하좌우
int dx[] = { 1,-1,0,0 };
int dy[] = { 0,0,1,-1 };

int ans = -1; //답

void func(int x, int y, int z, int k) {
	visit[x][y] = true;
	if (z == 4) { //조각 4개를 먹으면
		ans = max(ans, k); //답으로 큰 값을 찾는다.
		return;
	}
	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (1 <= nx && nx <= N && 1 <= ny && ny <= M && !visit[nx][ny]) { //범위 안에 있고 방문하지 않은 조각이면
			func(nx, ny, z + 1, k + mat[nx][ny]); //그 조각으로 탐색
			visit[nx][ny] = false; //탐색이 종료되고 미방문처리
		}
	}
} 

//ㅗ모양
void anofunc(int i, int j) {
	if (1 <= i - 1 && i + 1 <= N && 1 <= j - 1 && j - 1 <= M) { //ㅗ모양
		ans = max(mat[i - 1][j] + mat[i][j] + mat[i + 1][j] + mat[i][j - 1], ans);
	}
	if (1 <= i - 1 && i + 1 <= N && 1 <= j + 1 && j + 1 <= M) { //ㅜ모양
		ans = max(mat[i - 1][j] + mat[i][j] + mat[i + 1][j] + mat[i][j + 1], ans);
	}
	if (1 <= i + 1 && i + 1 <= N && 1 <= j - 1 && j + 1 <= M) { //ㅏ모양
		ans = max(mat[i + 1][j] + mat[i][j] + mat[i][j - 1] + mat[i][j + 1], ans);
	}
	if (1 <= i - 1 && i - 1 <= N && 1 <= j - 1 && j + 1 <= M) { //ㅓ모양
		ans = max(mat[i - 1][j] + mat[i][j] + mat[i][j - 1] + mat[i][j + 1], ans);
	}
}

int main() {
	cin >> N >> M;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			cin >> mat[i][j];
		}
	}

	//각각의 조각마다 탐색
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			memset(visit, false, sizeof(bool) * MAX * MAX);
			func(i, j, 1, mat[i][j]);
			anofunc(i, j);
		}
	}

	cout << ans;
}

 

'백준' 카테고리의 다른 글

백준14502 - 연구소  (0) 2020.02.18
백준2636 - 치즈  (0) 2020.02.17
백준4485 - 녹색 옷 입은 애가 젤다지?  (0) 2020.02.15
백준2688 - 줄어들지 않아  (0) 2020.02.15
백준2206 - 벽 부수고 이동하기  (0) 2020.02.13