[BAEKJOON] 14500번 테트로미노

2024. 4. 6. 20:39·Algorithm/Brute Force

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

 

14500번: 테트로미노

폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변

www.acmicpc.net

문제조건
  1. 연결된 4개의 정사각형 블록으로 모양을 만든다.
  2. 만들어진 모양을 종이위에 올렸을때, 4개의 숫자의 합의 최댓값은?
접근방법

완전탐색을 위해서 brute force로 접근해봤다.

그래서 전체 map을 돌면서 DFS를 수행할 수 있도록 구현했다.

#include <iostream>
using namespace std;

int n, m, map[501][501], visited[501][501];
int dy[] = { -1, 0 , 1, 0 };
int dx[] = { 0, -1, 0, 1 };
int res;

void dfs(int y, int x, int cnt, int sum) {
	if (cnt == 4) {
		res = max(res, sum);
		return;
	}
	for (int i = 0; i < 4; i++) {
		int ny = y + dy[i];
		int nx = x + dx[i];
		if (ny >= n || nx >= m || ny < 0 || nx < 0) continue;
		if (!visited[ny][nx]) {
			visited[ny][nx] = 1;
			dfs(ny, nx, cnt + 1, sum + map[ny][nx]);
			visited[ny][nx] = 0;
		}
		
	}
}


int main(){
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			int a;
			cin >> a;
			map[i][j] = a;
		}
	}
	//brute force
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			visited[i][j] = 1;
			dfs(i, j, 1, map[i][j]);
			visited[i][j] = 0;
		}
	}
	cout << res;
}

역시나,, 그렇게 쉽게 풀릴 문제는 아닌 것 같다.

생각을 해보자. DFS로 탐색을 돌리면, 계속 깊어지기만 하기 때문에

중간에 튀어나온 저 모양을 커버해주지 못한다.

그렇다면 저 모양을 커버하기 위해선 어떻게 해야할까?

중간에 튀어나온 모양을 제외한 모양들은 DFS로 이미 다 커버가 되었으므로, 저 모양에 대한 로직만 추가해주면된다.

어렵게 생각할 필요없이, 다시 Brute Force방식으로 찾아준다.

 

소스코드
#include <iostream>
using namespace std;

int n, m, map[502][502], visited[502][502];
int dy[] = { -1, 0 , 1, 0 };
int dx[] = { 0, -1, 0, 1 };
int res;

void dfs(int y, int x, int cnt, int sum) {
	if (cnt == 4) {
		res = max(res, sum);
		return;
	}
	for (int i = 0; i < 4; i++) {
		int ny = y + dy[i];
		int nx = x + dx[i];
		if (ny > n || nx > m || ny < 1 || nx < 1) continue;
		if (!visited[ny][nx]) {
			visited[ny][nx] = 1;
			dfs(ny, nx, cnt + 1, sum + map[ny][nx]);
			visited[ny][nx] = 0;
		}
		
	}
}


int main(){
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			int a;
			cin >> a;
			map[i][j] = a;
		}
	}
	//brute force
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			visited[i][j] = 1;
			dfs(i, j, 1, map[i][j]);
			visited[i][j] = 0;
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			int mid = map[i][j];
			int low = 1001;
			for (int k = 0; k < 4; k++) {
				low = min(low, map[i + dy[k]][j + dx[k]]);
				mid += map[i + dy[k]][j + dx[k]];
			}
			res = max(res, mid - low);
		}
	}
	cout << res;
}

우선 십자가 모양을 만들어서 테두리의 4가지중 하나를 빼서 모양을 만드는 방식으로 갔다.

그래서 맵 전체를 돌면서 가운데 값을 하나씩 잡아두고, dy, dx를 이용해서 각 테두리 4개를 방문해서 가장 작은 값을 기록해둔다. 그리고 이전 DFS로 구한 res값과 비교해서 더 크다면 res값을 갱신한다.

 

'Algorithm > Brute Force' 카테고리의 다른 글

[BAEKJOON] 14502번 연구소  (0) 2024.04.07
[BAEKJOON] 7568번 덩치  (0) 2024.03.20
[BAEKJOON] 1057번 토너먼트  (0) 2024.03.06
'Algorithm/Brute Force' 카테고리의 다른 글
  • [BAEKJOON] 14502번 연구소
  • [BAEKJOON] 7568번 덩치
  • [BAEKJOON] 1057번 토너먼트
Ls._.Rain
Ls._.Rain
안되면 될때까지 삽질했던 기록
  • Ls._.Rain
    Ls{Diary}
    Ls._.Rain
  • 전체
    오늘
    어제
    • 분류 전체보기 (136)
      • Github (2)
      • Spring (51)
        • Batch Programming (13)
        • 결제 (4)
        • 대용량 트래픽 (32)
        • OpenAI (0)
        • Security (0)
        • WebSocket (0)
        • JPA (1)
      • Algorithm (67)
        • DFS (6)
        • BFS (6)
        • Dynamic Programming (10)
        • Brute Force (4)
        • Binary Search (6)
        • 구현, 시뮬레이션 (15)
        • Stack (1)
        • Greedy (4)
        • Priority_Queue (2)
        • Back Tracking (3)
        • Geometry (2)
        • SCC (1)
        • 투포인터 (4)
        • 최대유량 (1)
        • 정렬 (1)
      • OS (0)
      • DevOps (15)
        • AWS (11)
        • Docker (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • hELLO· Designed By정상우.v4.10.0
Ls._.Rain
[BAEKJOON] 14500번 테트로미노
상단으로

티스토리툴바