일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
Tags
- 구현
- 12100번
- 백준
- 1등당첨기원
- nextcamp
- 2020 카카오 인턴
- 카카오 인턴
- 삼성A형
- C++
- 카카오 서류
- 채용연계형
- 개발자
- 백트래킹
- 카카오 여름 인턴
- 여름 인턴십
- 프로그래머스
- 14890번
- 2020 kakao
- 2020
- 삼성전자 3급
- Dev-matching
- BOJ
- 카카오 전환
- 알고리즘
- MapStruct
- Baekjoon
- Summer Intern
- 카카오
- Lombok-MapStruct-binding
- 카카오 면접
Archives
- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
Tags
- 구현
- 12100번
- 백준
- 1등당첨기원
- nextcamp
- 2020 카카오 인턴
- 카카오 인턴
- 삼성A형
- C++
- 카카오 서류
- 채용연계형
- 개발자
- 백트래킹
- 카카오 여름 인턴
- 여름 인턴십
- 프로그래머스
- 14890번
- 2020 kakao
- 2020
- 삼성전자 3급
- Dev-matching
- BOJ
- 카카오 전환
- 알고리즘
- MapStruct
- Baekjoon
- Summer Intern
- 카카오
- Lombok-MapStruct-binding
- 카카오 면접
Archives
- Today
- Total
슬기로운개발생활
[백준] 14890번 경사로 C++ 본문
https://www.acmicpc.net/problem/14890
14890번: 경사로
첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은 자연수이다.
www.acmicpc.net
문제이해
우선 N이 그렇게 크지 않아 문제를 보자마자 완전탐색이라는 생각이 들었다.
그리고 문제의 조건이 굉장히 많아 보이는데 생각해보면 간단히 해결되는 문제인 것 같다.
제일 중요한 것은, 오르막이나 내리막을 만났을 때 낮은 길에 L만큼의 경사로를 설치할 수 있느냐? 없느냐?
이것만 탐색해준다면 쉽게 해결되는 문제이다.
나는 row마다 탐색하는 함수와 col마다 탐색하는 함수를 따로 썼는데 둘 다 로직이 비슷해서 하나의 함수로 합치고 싶었지만...더 깔끔해질 것 같지 않아서 결국 따로 작성했다. ㅠㅠㅠ
풀이과정
- 한 행씩 for문을 통해 탐색한다.
- 현재 위치와 다음 위치의 높이차(diff = current - next)를 계산한다. 해당 값이 1이라면 현재 위치가 높은 위치이니 내리막길을 설치해야 할 것이고, -1이라면 낮은 위치이니 오르막길을 설치해야 할 것이다. 해당값이 0이라면 continue로 계속 탐색을 진행하고, 그 외의 값이라면 해당 row 탐색은 중단하고 다음 row로 넘어간다.
- 문제 조건에 따르면 경사로를 설치할 때 무조건 L 길이만큼 설치해야 한다.
- diff == 1 이라면 (next ≤ idx < next + L)의 idx 값이 모두 map[row][next] 값과 같아야 경사로를 설치 할 수 있다.
- 해당 idx를 탐색하는 도중 범위를 벗어나거나 다른 값이 있다면 해당 행에는 경사로를 설치할 수 없으므로 break한다.
- 위의 사항만 구현할 경우 예외상황이 발생한다. 해당 행의 값이 (3 3 2 2 3 3) 일 경우이다.
- 경사로를 설치한 자리에는 다시 설치할 수 없다. 따라서 row_visit(행 탐색할 때), col_visit(열 탐색할 때)배열을 선언하여 3-1번 에서 경사로를 설치할 때 마다 row_visit의 값을 설정해준다.
- 또한 3-1의 조건을 수정해야 한다. map[row][next] == map[row][idx] && !row_visit[row][idx] 이 두개 조건을 만족해야 경사로를 설치할 수 있다.
- 해당 행의 끝까지 탐색했다면 answer 값을 1 더해준다.
- 열 탐색은 1 ~ 4번 까지 행 열 값만 바꾸고 진행하면 된다.
소스코드
#include <iostream>
#include <vector>
using namespace std;
int N, L, answer;
vector<vector<int>> map;
vector<vector<bool>> rvisit, cvisit;
void solution_row() {
for (int r = 0; r < N; r++) {
bool success = true;
for (int c = 0; c < N - 1; c++) {
// diff == 1이면 다음 길까지 내리막길
// diff == -1이면 다음 길까지 오르막길
int diff = map[r][c] - map[r][c + 1];
if (diff == 0)
continue;
else if (abs(diff) > 1) {
success = false;
break;
}
int height = diff == 1 ? map[r][c + 1] : map[r][c];
int startidx = diff == 1 ? c + 1 : c - L + 1;
int endidx = diff == 1 ? c + L : c;
if (startidx < 0 || endidx >= N) {
success = false;
break;
}
int wayCount = 0;
for (int k = startidx; k <= endidx; k++) {
if (map[r][k] == height && !rvisit[r][k]) {
wayCount++;
rvisit[r][k] = true;
}
else
break;
}
if (wayCount == L) {
diff == 1 ? c = endidx - 1 : c = endidx;
}
else {
success = false;
break;
}
}
if (success)
answer++;
}
}
void solution_col() {
for (int c = 0; c < N; c++) {
bool success = true;
for (int r = 0; r < N - 1; r++) {
// diff == 1이면 다음 길까지 내리막길
// diff == -1이면 다음 길까지 오르막길
int diff = map[r][c] - map[r + 1][c];
if (diff == 0)
continue;
else if (abs(diff) > 1) {
success = false;
break;
}
int height = diff == 1 ? map[r + 1][c] : map[r][c];
int startidx = diff == 1 ? r + 1 : r - L + 1;
int endidx = diff == 1 ? r + L : r;
if (startidx < 0 || endidx >= N) {
success = false;
break;
}
int wayCount = 0;
for (int k = startidx; k <= endidx; k++) {
if (map[k][c] == height && !cvisit[k][c]) {
wayCount++;
cvisit[k][c] = true;
}
else
break;
}
if (wayCount == L) {
diff == 1 ? r = endidx - 1 : r = endidx;
}
else {
success = false;
break;
}
}
if (success)
answer++;
}
}
int main() {
cin >> N >> L;
map.resize(N, vector<int> (N, 0));
rvisit.resize(N, vector<bool>(N, false));
cvisit.resize(N, vector<bool>(N, false));
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
cin >> map[i][j];
solution_row();
solution_col();
printf("%d\n", answer);
return 0;
}
'Algorithm' 카테고리의 다른 글
[백준] 12100번 2048 (Easy) C++ (0) | 2020.05.20 |
---|---|
[백준] 14499번 주사위 굴리기 (0) | 2020.05.17 |
[백준] 13460번 구슬탈출2 C++ (0) | 2020.05.06 |
[백준] 2629번 양팔저울 C++ (0) | 2020.04.29 |
[백준] 1759번 암호만들기 C++ (0) | 2020.04.28 |
Comments