Link https://www.acmicpc.net/problem/14890
소스결과 2088 KB / 0 ms
출처 Baekjoon
언어 C++ 17
분류 시뮬레이션
설명
N x N 지도가 주어졌을 때 l길이의 경사로를 놓아 지나갈 수 있는 경로의 갯수를 출력해준다.
경사로를 놓기 위해서는 높이의 차이가 1이어야한다. 또한 경사로는 겹쳐서 놓을 수가 없다.
범위를 벗어나서는 안된다. 경사로의 개수는 무제한이다.
위 조건을 만족 하기 위해서 경사로를 놓은 위치를 기억해야한다. 각 줄에 대해서 독립 시행이기때문에
과거의 결과를 저장하면 안됬었다.
세로와 가로가 같은 방식의 알고리즘이지만 한개의 함수로 묶어서 구현하면 생각보다 구현이 복잡해 나눠서 구현했다.
BFS/DFS가 없는 순수한 구현 문제이기때문에 쉽다.
알고리즘
1. N x N 지도와 경사로의 길이 l을 입력 받는다.
2. 0 ~ N 까지 가로와 세로에 대해서 경사로를 놓는 모습을 시뮬레이션 한다.
2 - 1. 현재 시행에 대해서 경사로를 놓은 위치를 저장하기 위한 변수를 선언한다.
2 - 2. 현재위치와 다음 위치의 높이가 다른 경우 경사로를 놓을수 있는지 판단한다.
2 - 2 - 1. 높이가 1 증가하는 경우 다음칸 부터 l 칸이 높이가 같은지 판별해 경사로를 놓는 판단을 한다.
2 - 2 - 2. 높이가 1 감소하는 경우 현재 칸부터 뒤로 l 칸이 높이가 같은지 판별해 경사로를 놓는 판단을 한다.
2 - 2 - 2. 이외의 경우 경사로를 놓을 수 없다.
2 - 3. 경사로가 겹치지 않는다면 경사로를 놓은 다음 위치로 옮긴 후 반복을 진행한다.
3. 경사로를 놓은 수를 출력한다.
소스코드
#include <iostream>
using namespace std;
const short MAX = 100;
short board[MAX][MAX];
bool checkVertical(const int row, int max, int len)
{
bool stair[MAX] = {};
for (int cur = 0; cur < max;)
{
int next = cur + 1;
if (next == max)
break;
if (board[cur][row] == board[next][row])
cur = next;
else if (board[cur][row] - 1 == board[next][row])
{
if (cur + len >= max)
return false;
short origin = board[next][row];
for (int i = 0; i < len; i++)
if (stair[next + i] || origin != board[next + i][row])
return false;
else
stair[next + i] = true;
cur += len;
}
else if (board[cur][row] + 1 == board[next][row])
{
if (next - len < 0)
return false;
short origin = board[cur][row];
for (int i = 0; i < len; i++)
if (stair[cur - i] || origin != board[cur - i][row])
return false;
else
stair[cur - i] = true;
cur = next;
}
else
return false;
}
return true;
}
bool checkHorizontal(int col, int max, int len)
{
bool stair[MAX] = {};
for (int cur = 0; cur < max;)
{
int next = cur + 1;
if (next == max)
break;
if (board[col][cur] == board[col][next])
cur = next;
else if (board[col][cur] - 1 == board[col][next])
{
if (cur + len >= max)
return false;
short origin = board[col][next];
for (int i = 0; i < len; i++)
if (stair[next + i] || origin != board[col][next + i])
return false;
else
stair[next + i] = true;
cur += len;
}
else if (board[col][cur] + 1 == board[col][next])
{
if (next - len < 0)
return false;
short origin = board[col][cur];
for (int i = 0; i < len; i++)
if (stair[cur - i] || origin != board[col][cur - i])
return false;
else
stair[cur - i] = true;
cur = next;
}
else
return false;
}
return true;
}
int main()
{
int n, l;
int res = 0;
cin >> n >> l;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> board[i][j];
for (int i = 0; i < n; i++)
{
res += checkVertical(i, n, l);
res += checkHorizontal(i, n, l);
}
cout << res;
return 0;
}
'Algorithm > Simulation' 카테고리의 다른 글
Baekjoon 17144 미세먼지 안녕! (0) | 2019.04.18 |
---|---|
Baekjoon 17143 낚시왕 (0) | 2019.04.18 |
Baekjoon 3190 뱀 (0) | 2019.03.09 |
Baekjoon 14499 주사위 굴리기 (0) | 2019.03.09 |
Baekjoon 14891 톱니바퀴 (0) | 2019.03.08 |