문제 출처: https://www.acmicpc.net/problem/14500
대충 어렇게 코드를짜겠다고 생각했으나 구현을 못해서 구글링을 하여 도움을 얻은 문제입니다.
https://jaimemin.tistory.com/623 글을 참조했습니다.
풀이
제가 생각하는 구현에 있어서 가장 중요한 부분은
1. 백트래킹기법을 쓸줄아느냐?(대충 이해하고 넘어가니 구현할 때 손도못댑니다.)
2. ㅗ,ㅜ,ㅏ,ㅓ의 도형 모양과 다른 테트로미노 도형의 모양의 차이가 무엇인지 아느냐?(dfs의 깊이가 다름을 관찰했나?)
3. 1,2번을 관찰하고 정확히 구현할줄 아는가?
이 3가지라고생각합니다.
구현에 있어서 중요한 것은 ㅗ,ㅜ,ㅏ,ㅓ의 모양은 다른 모양들과 dfs깊이가 다르므로 따로 처리해주고, 나머지 모양은 모양과 상관없이
시작점부터 일반적인dfs를 돌려주면 된다는 것입니다.(4번째 탐색했을 때 함수를 종료하면됩니다.) 모든 범위에서 탐색하므로 모든 모양들에 대해 탐색하기때문입니다.
그리고, ㅗ,ㅜ,ㅏ,ㅓ를 처리해줄 때 범위의 조건을 정확히 작성해야합니다. 이게 의외로 까다롭습니다. test case는 다 맞는데 게시판에있는 반례를 입력하니 범위가 이상해서 다른 답들이 나왔습니다.
사실 많이 허무하잖아요. 자신있게 풀었는데 반례때문에 그 문제가 통째로 틀리게되는거니깐....자기가 스스로 몇개의 경우를 만들어서 더 돌려보는 습관을 가져야겠습니다.
마지막으로, 제일 중요한것은 백트래킹의 소스구현입니다. 이부분은 설명이 힘드니 소스코드로 확인해주세요.
코드
#include<iostream> #include<algorithm> using namespace std; int map[500][500], check[500][500], n, m; int dx[4] = { -1,1,0,0 }; int dy[4] = { 0,0,-1,1 }; int dfs(int y, int x, int cnt); int func(int y, int x); int main() { cin.tie(0); cin.sync_with_stdio(false); cin >> n >> m; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> map[i][j]; } } int ans = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { check[i][j] = 1; //반환받아서 그 값으로 비교하기 //1. 일반적인 dfs ans = max(ans, dfs(i, j, 1)); //ㅗ,ㅓ,ㅏ,ㅜ의 특별한 형태 ans = max(ans, func(i, j)); //백트래킹 check[i][j] = 0; } } cout << ans << '\n'; } int dfs(int y, int x, int cnt) { int sum = 0; if (cnt == 4) { return map[y][x]; } for (int i = 0; i < 4; i++) { int ny = y + dy[i]; int nx = x + dx[i]; if (ny >= 0 && nx >= 0 && ny < n && nx < m && !check[ny][nx]) { check[ny][nx] = 1; sum = max(sum, map[y][x] + dfs(ny, nx, cnt + 1)); check[ny][nx] = 0; } } return sum; } int func(int y, int x) { int sum = 0; //ㅏ if (y - 1 >= 0 && y + 1 < n && x + 1 < m) sum = max(sum, map[y][x] + map[y - 1][x] + map[y + 1][x] + map[y][x + 1]); //ㅓ if (y - 1 >= 0 && y + 1 < n && x + 1 < m) sum = max(sum, map[y][x] + map[y - 1][x + 1] + map[y + 1][x + 1] + map[y][x + 1]); //ㅗ if (y - 1 >= 0 && x - 1 >= 0 && x + 1 < m) sum = max(sum, map[y - 1][x] + map[y][x] + map[y][x - 1] + map[y][x + 1]); //ㅜ if (y + 1 < n && x - 1 >= 0 && x + 1 < m) sum = max(sum, map[y][x] + map[y][x - 1] + map[y][x + 1] + map[y + 1][x]); return sum; }
결과
'문제풀이(BOJ) > 삼성 sw역량테스트 기출' 카테고리의 다른 글
[백준 15685] 드래곤 커브 (0) | 2020.02.04 |
---|---|
[백준 16235] 나무 재테크 (0) | 2020.02.02 |
[백준17070] 파이프 옮기기1 (0) | 2020.01.30 |
[백준 17144] 미세먼지 안녕! (0) | 2020.01.29 |
[백준 3190] 뱀 (0) | 2020.01.29 |