-
[Brute Force] BOJ 14500 : 테트로미노백준 문제풀이/BRUTE FORCE 2019. 9. 6. 01:41
문제(삼성 sw 기출문제)
폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다.
- 정사각형은 서로 겹치면 안 된다.
- 도형은 모두 연결되어 있어야 한다.
- 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다.
정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다.
아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누어져 있으며, 각각의 칸에는 정수가 하나 쓰여 있다.
테트로미노 하나를 적절히 놓아서 테트로미노가 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성하시오.
테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야 하며, 회전이나 대칭을 시켜도 된다.
입력
첫째 줄에 종이의 세로 크기 N과 가로 크기 M이 주어진다. (4 ≤ N, M ≤ 500)
둘째 줄부터 N개의 줄에 종이에 쓰여 있는 수가 주어진다. i번째 줄의 j번째 수는 위에서부터 i번째 칸, 왼쪽에서부터 j번째 칸에 쓰여 있는 수이다. 입력으로 주어지는 수는 1,000을 넘지 않는 자연수이다.
출력
첫째 줄에 테트로미노가 놓인 칸에 쓰인 수들의 합의 최댓값을 출력한다.
풀이
테트로미노의 모양은 19가지가 있습니다.
물론 이 19가지의 경우를 각각 만들어서 for문을 돌리는 것도 방법입니다.
하지만
이렇게 한다면 면접에서 좋은 점수를 받기는 힘들 것 입니다.
테트로미노의 특징을 잘 보면 연속적인 4개의 블록을 이동해서 나올 수 있는
모든 경우의 수와 같습니다.
단,
"ㅗ,ㅜ,ㅓ,ㅏ" 모양은 갈림길이 존재하기 때문에 재귀 함수로 구현이 힘드니
예외사항으로 하드코딩을 했습니다.
모든 경우의 수를 탐색하는 go() 함수를 만들기 위해서는
다음과 같은 상황을 고려할 필요가 있습니다.
1. 4개의 블록을 탐색한 경우
2. 배열을 벗어난 경우
3. 이미 탐색한 블록을 만난 경우
이러한 상황이 발생하면 함수를 종료하도록 해줍시다.
자세한 설명은 코드에 있습니다.
코드
#include <iostream> using namespace std; int arr[500][500]; bool c[500][500]; int n, m; int ans = 0; int dx[] = { 0,0,1,-1 }; int dy[] = { 1,-1,0,0 }; //4번의 이동으로 만들 수 있는 모든 경우의 수를 탐색 //ㅗ ㅜ ㅓ ㅏ 모양은 예외 사항이다. void go(int x, int y, int sum, int cnt) { //4번 움직였으면 if (cnt == 4) { if (sum > ans) ans = sum; return; } // 배열을 벗어나면 if (x < 0 || x >= n || y < 0 || y >= m) return; //이미 탐색했다면 if (c[x][y]) return; c[x][y] = true; //4번 이동하는 모든 경우의 수 for (int k = 0; k < 4; k++) { go(x + dx[k], y + dy[k], sum + arr[x][y], cnt+1); } //탐색이 끝나면 다시 초기화 c[x][y] = false; } int main(){ cin >> n >> m; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) cin >> arr[i][j]; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { go(i, j, 0, 0); int temp = 0; //예외사항 if (i + 2 < n && j + 1 < m) { temp = arr[i][j] + arr[i + 1][j] + arr[i + 2][j] + arr[i + 1][j + 1]; if (temp > ans) ans = temp; } if (i + 2 < n && j - 1 >= 0) { temp = arr[i][j] + arr[i + 1][j] + arr[i + 2][j] + arr[i + 1][j - 1]; if (temp > ans) ans = temp; } if (i - 1 >= 0 && j + 2 < m) { temp = arr[i][j] + arr[i][j + 1] + arr[i][j + 2] + arr[i - 1][j + 1]; if (temp > ans) ans = temp; } if (i + 1 < n && j + 2 < m) { temp = arr[i][j] + arr[i][j + 1] + arr[i][j + 2] + arr[i + 1][j + 1]; if (temp > ans) ans = temp; } } } cout << ans << '\n'; return 0; }
'백준 문제풀이 > BRUTE FORCE' 카테고리의 다른 글
BOJ 1759 : 암호 만들기 (0) 2020.01.29 BOJ 2529 : 부등호 (0) 2020.01.12 [Brute Force] BOJ 6603번 : 로또 (0) 2019.07.07 [Brute Force] BOJ 1476 번 : 날짜 계산 (0) 2019.06.25 [Brute Force] BOJ 2309 번 : 일곱 난쟁이 (0) 2019.06.25