-
백준 14890 경사로Algorithm/구현(Brute force, Back tracking, etc.) 2021. 11. 16. 14:04728x90
- 단순(하지만 시간이 많이 걸리는) 구현 문제이다. 시간복잡도는 O(n^2)이다.
- 각 행과 각 열에 대해 test를 거쳐서, 경사로를 놓아 지나갈 수 있는 길을 몇 개나 만들 수 있는지를 체크하면 된다.
따라서, check하는 함수를 따로 두고 vector를 넘겨서 체크하도록 하였다. 만약 이렇게 하지 않는다면 4중 for문이 되어 코드의 가독성이 많이 떨어지게 된다.
- 조건에 따라 분기를 해 준다.
1. 인접한 두 개의 칸을 비교해서 높이가 다른 경우
1) 두 칸의 높이 차가 1을 초과하는 경우 -> false
2) 두 칸의 차이가 1인 경우
(1) 이전 칸이 다음 칸보다 작은 경우
=> 이전 칸(i-1)에서 l 길이 만큼의 블록들을 체크 해 간다.
=> i-1칸과 높이가 다르다면 false / 이미 경사로가 놓여있다면 false / 주어진 범위를 벗어나는 경우 false
(2) 이전 칸이 다음 칸보다 큰 경우
=> 다음 칸(i)에서 l 길이 만큼의 블록들을 체크 해 간다.
=> i칸과 높이가 다르다면 false / 이미 경사로가 놓여있다면 false / 주어진 범위를 벗어나는 경우 false
#include <iostream> #include <vector> using namespace std; int arr[100][100]; int n, l; bool check(vector<int> &c) { vector<bool> existed(n, false); for (int i = 1; i < n; i++) { if (c[i] != c[i - 1]) { int diff = abs(c[i] - c[i - 1]); if (diff > 1) return false; if (c[i] > c[i - 1]) { for (int j = 0; j < l; j++) { if (i -1- j < 0) return false; if (c[i-1] != c[i -1 - j]) return false; if (existed[i - 1 - j]) return false; existed[i - 1 - j] = true; } } else if (c[i] < c[i - 1]) { for (int j = 0; j < l; j++) { if (i + j >= n) return false; if (c[i] != c[i + j]) return false; if (existed[i + j]) return false; existed[i + j] = true; } } } } return true; } int main() { int answer = 0; cin >> n >> l; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cin >> arr[i][j]; } } // 가로 체크 for (int i = 0; i < n; i++) { vector<int> a; for (int j = 0; j < n; j++) { a.push_back(arr[i][j]); } if (check(a)) answer++; } // 세로 체크 for (int i = 0; i < n; i++) { vector<int> b; for (int j = 0; j < n; j++) { b.push_back(arr[j][i]); } if (check(b)) answer++; } cout << answer; return 0; }
'Algorithm > 구현(Brute force, Back tracking, etc.)' 카테고리의 다른 글
백준 15683 감시 (0) 2021.11.17 백준 14891 톱니바퀴 (0) 2021.11.16 백준 14889 스타트와 링크 (0) 2021.11.15 백준 14888 연산자 끼워넣기 (0) 2021.11.15 백준 14503 로봇 청소기 (0) 2021.11.15