백준문제풀이/구현

14890번-경사로

문제

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

 

14890번: 경사로

첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은 자연수이다.

www.acmicpc.net


접근방법

1) 접근 사고

정말 구현문제 그 자체였습니다. 특별한 알고리즘 없이 구현력만 보는 문제인데 문제 설명이 저는 한 번에 이해가가지 않아서 어려웠습니다.

자세한 동작은 주석 첨부 하였습니다.

 

2) 시간 복잡도

O(n^2)

 

3) 배운 점

breack과 continue 사용 연습을 엄청 한 문제였습니다.

 

4) PS

문제 이해가 너무 어려웠다.


정답 코드

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include<bits/stdc++.h>
#define fastio ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define pii pair<int,int>
#define mp(X,Y) make_pair(X,Y)
#define mt(X,Y) make_tuple(X,Y)
#define mtt(X,Y,Z) make_tuple(X,Y,Z)
#define ll long long
#define sz(v) (int)(v).size()
 
using namespace std;
const int MAX = 100;
int n, l;
int board[MAX][MAX];
bool visited[MAX];
int ret;
 
 
int main(void)
{
    fastio;
    cin >> n >> l;
 
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            cin >> board[i][j];
        }
    }
 
    auto checkRow = [&](int y) -> void{
        int cur = board[y][0];
        for(int i = 0; i < n; i++){
            //값이 다른 경우라면
            if(board[y][i] != cur){
                //경사로의 높이가 1이 아니라면
                if(!(abs(board[y][i] - cur) <= 1))
                    return ;
                //내리막길일 경우
                if(board[y][i] < cur){
                    int height = -1;
                    //아직 방문하지 않은 곳이고 내리막길을 만들려는 범위가 n을 초과하지 않는다면
                    for(int j = i; j < i + l; j++){
                        if(!visited[j] && j < n){
                            visited[j] = true;
                            //L길이만큼 같은 높이기가 아니라면 조건 충족 X
                            if (height == -1){
                                height = board[y][j];
                                continue;
                            }
                            if(height != -1 && board[y][j] != height)
                                return;
                        }
                        else
                            return;
                    }
                    //내리막길을 설치한 경로만큼 탐색 인덱스 증가
                    i += l - 1;
                    //초과할 경우 탐색 종료
                    if(i >= n)
                        break;
                }
                else{
                    int height = -1;
                    for (int j = i - 1; j > i - 1 - l; j--){
                        if(!visited[j] && j >= 0)
                        {
                            visited[j] = true;
                            if(height == - 1)
                            {
                                height = board[y][j];
                                continue;
                            }
                            if (height != -1 && board[y][j] != height)
                                return;
                        }
                        else
                            return;
                    }
                }
                cur = board[y][i];
            }
        }
        ret++;
    };
 
    auto checkCol = [&](int x) -> void {
        int cur = board[0][x];
        for(int i = 0; i < n; i++){
            if(board[i][x] != cur){
                if(!(abs(board[i][x] - cur) <= 1))
                    return;
                if(board[i][x] < cur){
                    int height = -1;
                    for(int j = i; j < i + l; j++){
                        if(!visited[j] && j < n){
                            visited[j] = true;
                            if(height == - 1){
                                height = board[j][x];
                                continue;
                            }
                            if(height != -1 && board[j][x] != height){
                                return;
                            }
                        }
                        else
                            return;
                    }
                    i += l - 1;
                    if(i >= n)
                        break;
                }
                else{
                    int height = -1;
                    for(int j = i - 1; j > i - 1 - l; j--){
                        if(!visited[j] && j >= 0){
                            visited[j] = true;
                            if(height == -1){
                                height = board[j][x];
                                continue;
                            }
                            if(height != - 1 && board[j][x] != height)
                                return;
                        }
                        else
                            return;
                    }
                }
                cur = board[i][x];
            }
        }
        ret++;
    };
 
    for(int i = 0; i < n; i++){
        memset(visited, falsesizeof visited);
        checkRow(i);
    }
    for(int i = 0; i < n; i++){
        memset(visited, falsesizeof visited);
        checkCol(i);
    }
    cout << ret << "\n";
}
cs

'백준문제풀이 > 구현' 카테고리의 다른 글

15683번-감시  (0) 2021.09.07
14891번-톱니바퀴  (0) 2021.09.05
14503번-로봇청소기  (0) 2021.09.04
14502번-연구소  (0) 2021.09.03
14500번-테트로미노  (0) 2021.09.03