컴퓨터 사이언스/1고리즘
백준 14890 : 경사로
저세상 개발자
2021. 8. 16. 01:20
https://www.acmicpc.net/problem/14890
단순 구현문제다. N의 범위가 매우 작으므로 부르트포스로 풀면 된다.
행과 열에 대하여 모두 검사해야하므로 동일한 로직의 거의 비슷한 코드가 두 번 반복된다.
나는 이 부분을 하나의 함수에서 포인터를 사용하여 해결했다.
처음에 작성한 로직은 메인 함수 바로 위에 참고용으로 넣어뒀는데, idx를 증가시키면서 배열을 순회하는 while문 안에서 동일한 작동을 하는 while문을 다시 호출함으로써 코드가 지저분해졌다.
로직이 한 눈에 들어오지도 않고 특히 flat값과 idx값을 정해주는데 있어서 시간을 들여 고민할 필요가 있다.
반면에 깔끔한 코드는 이러한 부분들을 고민할 필요 없이 한 번의 while문을 돌면서 로직 안에서 처리된다.
#include <iostream>
#define BREAK flag=0;break
using namespace std;
int n, L;
int board[100][100];
//가독성이 뛰어난 코드
bool check(int i, bool dir) {
int idx, prev, cur, flat, tmp;
int *x, *y;
if (!dir) y = &i, x = &idx;
else x = &i, y = &idx;
idx = 0, flat = 1, prev = board[*y][*x];
for (idx = 1; idx < n; idx++) {
cur = board[*y][*x];
if (cur == prev) ++flat;
else if (prev == cur - 1 && flat >= L) flat = 1;
else if (prev == cur + 1 && flat >= 0) flat = -L + 1;
else break;
prev = cur;
}
return (idx == n && flat >= 0);
}
int find_path() {
int ret = 0;
for (int i = 0; i < n; i++) {
ret += check(i, 0);
ret += check(i, 1);
}
return ret;
}
void solution() {
cin >> n >> L;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> board[i][j];
}
}
cout << find_path();
}
//사용하지 않음
//처음에 사용한 코드, 지저분함 로직이 한 눈에 들어오지 않음
bool dirty_code_check(int i, bool dir) {
int idx, prev, cur, flat, tmp;
bool flag;
int* x, * y;
if (!dir) y = &i, x = &idx;
else x = &i, y = &idx;
idx = 0, prev = board[*y][*x], flat = 0, flag = 1;
while (idx < n) {
cur = board[*y][*x];
if (cur == prev) ++flat;
else if (prev == cur + 1 || prev == cur - 1) {
if (prev < cur) {
if (flat < L) { BREAK; }
flat = 1;
}
else {
//특히 이 부분에서 idx가 어떻게 변하는지, flat값을 어떻게 줘야하는지
//고민할 시간이 필요함. 밑에 check함수가 훨씬 가독성면에서 뛰어남
flat = 1;
++idx;
while (idx < n && flat < L && board[*y][*x] == cur) ++idx, ++flat;
if (flat < L) { BREAK; }
flat = 0;
--idx;
}
prev = cur;
}
else { BREAK; }
++idx;
}
return flag;
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
solution();
return 0;
}
메모리: 2060 kb | 시간: 0 ms |